fro*_*row 39 data-binding grails json grails-orm
我正在开发一个RESTful接口,用于为JavaScript应用程序提供JSON数据.
在服务器端,我使用Grails 1.3.7并使用GORM域对象进行持久化.我实现了一个自定义JSON Marshaller来支持编组嵌套域对象
以下是示例域对象:
class SampleDomain {
static mapping = { nest2 cascade: 'all' }
String someString
SampleDomainNested nest2
}
Run Code Online (Sandbox Code Playgroud)
和
class SampleDomainNested {
String someField
}
Run Code Online (Sandbox Code Playgroud)
SampleDomain资源在URL/rs/sample/so/rs/sample/1下发布,指向ID为1的SampleDomain对象
当我使用自定义json marshaller(/ rs/sample/1上的GET)渲染资源时,我得到以下数据:
{
"someString" : "somevalue1",
"nest2" : {
"someField" : "someothervalue"
}
}
Run Code Online (Sandbox Code Playgroud)
这正是我想要的.
现在出现了问题:我尝试通过PUT将相同的数据发送到资源/ rs/sample/1.
要将json数据绑定到域对象,处理请求的控制器调用def domain = SampleDomain.get(id)
以及domain.properties = data
数据是unmarshalled对象的位置.
"someString"字段的绑定工作得很好,但是嵌套对象没有使用嵌套数据填充,因此我得到一个错误,即属性"nest2"为null,这是不允许的.
我已经尝试过实现一个自定义PropertyEditorSupport
以及一个StructuredPropertyEditor
并为该类注册编辑器.
奇怪的是,当我提供非嵌套值时,编辑器才会被调用.所以当我通过PUT将以下内容发送到服务器时(这没有任何意义;))
{
"someString" : "somevalue1",
"nest2" : "test"
}
Run Code Online (Sandbox Code Playgroud)
至少会调用属性编辑器.
我查看了代码GrailsDataBinder
.我发现通过指定关联的路径而不是提供地图,设置关联的属性似乎有效,因此以下工作原理:
{
"someString" : "somevalue1",
"nest2.somefield" : "someothervalue"
}
Run Code Online (Sandbox Code Playgroud)
但这对我没有帮助,因为我不想为JSON对象序列化器实现自定义JavaScript.
是否可以使用嵌套映射使用Grails数据绑定?或者我是否真的要为每个域类手动实现它?
非常感谢,
马丁
由于这个问题多次被提出,我想分享我最后做的事情:
由于我有更多要求像安全性等那样实现,我实现了一个服务层,它隐藏了控制器中的域对象.我介绍了一个"动态DTO层",它将域对象转换为Groovy映射,可以使用标准序列化器轻松序列化并手动实现更新.我尝试实现的所有基于半自动/元编程/命令模式/ ...的解决方案在某些时候都失败了,主要是导致奇怪的GORM错误或许多配置代码(以及很多挫折).DTO的更新和序列化方法相当简单,可以非常快速地实现.它不会引入大量重复代码,因为如果您不想发布内部域对象结构,则必须指定域对象的序列化方式.也许这不是最优雅的解决方案,但它是唯一真正适合我的解决方案.它还允许我实现批量更新,因为更新逻辑不再连接到http请求.
但是我必须说,我不认为grails是最适合这种应用的合适的技术堆栈,因为它使你的应用程序非常重量和inflexbile.我的经验是,一旦你开始做一些默认情况下框架不支持的事情,它就开始变得凌乱.此外,我不喜欢grails中的"repository"层实际上只作为域对象的一部分存在,这引入了许多问题并导致几个"代理服务"模拟存储库层.如果您开始使用json rest接口构建应用程序,我建议您选择像node.js这样的轻量级技术,或者,如果您想/必须坚持使用基于Java的堆栈,请使用标准spring框架+ spring mvc + spring数据有一个漂亮干净的dto层(这是我迁移到的,它就像一个魅力).您不必编写大量的样板代码,而是完全控制实际发生的事情.此外,您可以获得强大的打字,从而提高开发人员的工作效率和可维护性,并使其他LOC合法化.当然,强大的打字意味着强大的工具!
我开始写一篇描述我想出的架构的博客文章(当然是一个示例项目),但是我现在没有很多时间来完成它.当它完成后,我将在这里链接到它以供参考.
希望这可以为遇到类似问题的人们提供灵感.
干杯!
它要求您提供类名:
{ class:"SampleDomain", someString: "abc",
nest2: { class: "SampleDomainNested", someField:"def" }
}
Run Code Online (Sandbox Code Playgroud)
我知道,它需要不同的输入和它产生的输出。
正如我之前在评论中提到的,使用 gson 库可能会更好。