将JSON绑定到嵌套的Grails域对象

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数据绑定?或者我是否真的要为每个域类手动实现它?

非常感谢,

马丁

fro*_*row 7

由于这个问题多次被提出,我想分享我最后做的事情:

由于我有更多要求像安全性等那样实现,我实现了一个服务层,它隐藏了控制器中的域对象.我介绍了一个"动态DTO层",它将域对象转换为Groovy映射,可以使用标准序列化器轻松序列化并手动实现更新.我尝试实现的所有基于半自动/元编程/命令模式/ ...的解决方案在某些时候都失败了,主要是导致奇怪的GORM错误或许多配置代码(以及很多挫折).DTO的更新和序列化方法相当简单,可以非常快速地实现.它不会引入大量重复代码,因为如果您不想发布内部域对象结构,则必须指定域对象的序列化方式.也许这不是最优雅的解决方案,但它是唯一真正适合我的解决方案.它还允许我实现批量更新,因为更新逻辑不再连接到http请求.

但是我必须说,我不认为grails是最适合这种应用的合适的技术堆栈,因为它使你的应用程序非常重量和inflexbile.我的经验是,一旦你开始做一些默认情况下框架不支持的事情,它就开始变得凌乱.此外,我不喜欢grails中的"repository"层实际上只作为域对象的一部分存在,这引入了许多问题并导致几个"代理服务"模拟存储库层.如果您开始使用json rest接口构建应用程序,我建议您选择像node.js这样的轻量级技术,或者,如果您想/必须坚持使用基于Java的堆栈,请使用标准spring框架+ spring mvc + spring数据有一个漂亮干净的dto层(这是我迁移到的,它就像一个魅力).您不必编写大量的样板代码,而是完全控制实际发生的事情.此外,您可以获得强大的打字,从而提高开发人员的工作效率和可维护性,并使其他LOC合法化.当然,强大的打字意味着强大的工具!

我开始写一篇描述我想出的架构的博客文章(当然是一个示例项目),但是我现在没有很多时间来完成它.当它完成后,我将在这里链接到它以供参考.

希望这可以为遇到类似问题的人们提供灵感.

干杯!


mom*_*omo 1

它要求您提供类名:

{ class:"SampleDomain", someString: "abc", 
nest2: { class: "SampleDomainNested", someField:"def" }
} 
Run Code Online (Sandbox Code Playgroud)

我知道,它需要不同的输入和它产生的输出。

正如我之前在评论中提到的,使用 gson 库可能会更好。