【发布时间】:2011-11-23 13:09:56
【问题描述】:
我正在开发一个 RESTful 接口,用于为 JavaScript 应用程序提供 JSON 数据。
在服务器端,我使用 Grails 1.3.7 并使用 GORM 域对象进行持久化。我实现了一个自定义 JSON Marshaller 来支持编组嵌套的域对象
以下是示例域对象:
class SampleDomain {
static mapping = { nest2 cascade: 'all' }
String someString
SampleDomainNested nest2
}
和
class SampleDomainNested {
String someField
}
SampleDomain 资源在 URL /rs/sample/ 下发布,因此 /rs/sample/1 指向 ID 为 1 的 SampleDomain 对象
当我使用自定义 json 编组器(GET on /rs/sample/1)呈现资源时,我得到以下数据:
{
"someString" : "somevalue1",
"nest2" : {
"someField" : "someothervalue"
}
}
这正是我想要的。
现在问题来了:我尝试通过 PUT 将相同的数据发送到资源 /rs/sample/1。
为了将 json 数据绑定到域对象,处理请求的控制器调用 def domain = SampleDomain.get(id) 和 domain.properties = data,其中 data 是未编组的对象。
“someString”字段的绑定工作正常,但嵌套对象未使用嵌套数据填充,因此我收到一个错误,即属性“nest2”为空,这是不允许的。
我已经尝试实现自定义 PropertyEditorSupport 以及 StructuredPropertyEditor 并为该类注册编辑器。
奇怪的是,只有在我提供非嵌套值时才会调用编辑器。因此,当我通过 PUT 将以下内容发送到服务器时(这没有任何意义;))
{
"someString" : "somevalue1",
"nest2" : "test"
}
至少调用了属性编辑器。
我查看了GrailsDataBinder 的代码。我发现通过指定关联的路径而不是提供地图来设置关联的属性似乎可以工作,因此以下内容也可以:
{
"someString" : "somevalue1",
"nest2.somefield" : "someothervalue"
}
但这对我没有帮助,因为我不想实现自定义 JavaScript 到 JSON 对象序列化器。
是否可以通过嵌套映射来使用 Grails 数据绑定?还是我真的要为每个域类手动实现它?
非常感谢,
马丁
【问题讨论】:
-
你也有自定义的 json unmarshaller 吗?
-
不,我没有自定义 json 解组器。我使用 request.JSON 解析请求。我想要的是一个属性编辑器,它支持从 Map 创建域对象以及按 ID 加载/映射域对象。
-
你试过这个插件了吗:grails.org/plugin/json-rest-api
-
感谢您的提示。我试过这个插件,但它只支持“平面”域对象,即所有关联都呈现为 ID。但是我在那个插件中找到了一些灵感。我想我要实现一个映射器,它的行为由域对象中的一些静态控制(即资源 url、引用的属性、嵌入的属性......)
-
你试过 gson 吗?你可能会更好地使用它......但我相信有一种方法可以通过 grails 方式实现。
标签: json data-binding grails grails-orm