0

我有一个标准 Spring Roo 项目,我正在尝试将其用作数据库的 REST API,使用 Web MVC 和自动生成的 JSON 控制器。我正在尝试发送 POST 请求以通过表单数据或 JSON(最好是 JSON)创建对象,但我收到了相当奇怪的行为。

我的分层实体有一个可选的对自身作为父级的引用。它看起来像这样:

public class LandType {
    private String name;
    private String description;

    @ManyToOne
    private LandType parent;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "parent")
    private Set<LandType> children = new HashSet<LandType>();

    @ManyToMany(cascade = CascadeType.ALL)
    private Set<Param> params = new HashSet<Param>();
}

当我尝试通过没有父值的 JSON POST 请求(只有名称和描述)创建新实例时,它可以工作。当我尝试使用父值创建它时(我使用父 ID 作为整数,因为这就是股票 Roo 表单所做的),我收到 Spring 错误:

java.lang.Integer cannot be cast to java.util.Map

我不知道它在尝试将任何东西转换为地图时在做什么,并且使用调试器进行跟踪是没有意义的。它通过控制器进入 fromJsonToLandType,然后尝试反序列化并最终抛出异常:

flexjson.factories.BeanObjectFactory.instantiate(BeanObjectFactory.java:17)
flexjson.ObjectBinder.bind(ObjectBinder.java:86)
flexjson.ObjectBinder.bindIntoObject(ObjectBinder.java:139)
flexjson.factories.ClassLocatorObjectFactory.instantiate(ClassLocatorObjectFactory.java:38)
flexjson.ObjectBinder.bind(ObjectBinder.java:86)
flexjson.ObjectBinder.bind(ObjectBinder.java:65)
flexjson.JSONDeserializer.deserialize(JSONDeserializer.java:158)
...

当我尝试将参数数组作为 {..., 'params': [10, 11]} 传递时,也会发生同样的事情。似乎 Spring Roo 不太知道如何处理非原始类型的 JSON 输入,或者我不知道以什么格式提供它们。我在这里做错了什么?

编辑

我主要是用 curl 来测试这个以准确控制输入的内容。一个示例调用是:

> curl -i -X POST -H "Content-type: application/json" -d "{'name':'test', 'description': 'test', 'parent': 8}" http://localhost:8080/mutopia-server/landtypes

... 其中 8 是现有 LandType 的 ID,并且再次删除parent使其工作。奇怪的是,我已经通过标准 Roo 控制器(-H "Content-type: application/json"-H "Accept: text/html"添加Accept: application/json也无济于事,因为此时调用了 JSON 控制器,但内部正在发生一些奇怪的事情。

4

1 回答 1

0

所以原因是 Flexjson(反序列化器)需要一个集合(或 JSON 数组)或 Param 对象(以 JSON 对象形式),但它却找到了一个整数数组。由于 Flexjson 对 Spring 或 Roo 一无所知,因此它不会将整数识别为 ID,并使用适当的 Finder 来查找它们,就像我天真希望的那样。

解决方案似乎是调用JSONDeserializer.deserialize(). 也许有一天这可能会成为@RooJson插件的一项功能(相关问题),但还没有。

于 2012-10-10T11:30:04.440 回答