【问题标题】:Grails get child domain objectsGrails 获取子域对象
【发布时间】:2013-10-09 06:27:42
【问题描述】:

我有两个域类,一个是父级,另一个是子级,它们之间有一个 hasMany 关系。父类有很多子类,子类属于父类。 这是编码示例。

class Parent{
   String name
    static hasMany = [childs:Child] 
    static constraints = {
   }
}


class Child{
   String name
   static belongsTo = [parent:Parent]
   static constraints={}
}

问题是,一旦我获得父对象,与父类关联的子对象也被获取。但是当我将对象转换为 JSON 时,我并没有完全看到子对象,我只能看到子对象的 ID。我想查看子对象的所有列,而不仅仅是 Id。

转换后的 JSON 响应:

[{"class":"project.Parent","id":1,
  "name":"name1","childs":[{"class":"Child","id":1},{"class":"Review","id":2}]}]

但我也想要包含子对象名称的响应,如下

[{"class":"project.Parent","id":1,"name":"name1",
  "childs":[{"class":"Child","id":1,"name":"childname1"},
            {"class":"Review","id":2,"name":"childname2"}
           ]
}]

非常感谢任何帮助。 提前致谢。

【问题讨论】:

    标签: json grails grails-domain-class


    【解决方案1】:

    问题在于使用默认 JSON 转换器。以下是您的选择:

     1. Default  -  all fields, shallow associations
        a. render blah as JSON
    
     2. Global deep converter - change all JSON converters to use deep association traversal
        a. grails.converters.json.default.deep = true
    
     3. Named config marshaller using provided or custom converters
        a. JSON.createNamedConfig('deep'){
            it.registerObjectMarshaller( new DeepDomainClassMarshaller(...) )
        }
        b. JSON.use('deep'){
            render blah as JSON
        }
    
     4. Custom Class specific closure marshaller 
        a. JSON.registerObjectMarshaller(MyClass){ return map of properties}
        b. render myClassInstance as JSON
    
     5. Custom controller based closure to generate a map of properties
        a. convert(object){
            return map of properties
        }
        b. render convert(blah) as JSON
    

    您当前使用的是默认选项 1。

    您可以做的最简单的方法是使用选项 2 设置全局深度转换器,但请注意这会影响您应用中的所有域类。这意味着,如果您有一个大型关联树,最终形成一个顶级对象,并且您尝试转换这些顶级对象的列表,那么深度转换器将执行所有查询以获取所有关联对象及其关联对象转动。 - 您可以一次性加载整个数据库 :) 小心。

    【讨论】:

    • 嘿,谢谢我使用了第三种方法 JSON.use('deap'){ render Parent as JSON } 它就像我预期的那样工作。
    • 我也有类似的问题,我的作品只在第一次工作,然后总是父类属性。我也在使用 JSON.use('deep')。
    【解决方案2】:

    最新的 grails 会自动进行深度转换,但您可能是延迟加载的受害者。

    访问时未加载子项,因此 JSON 转换器无法将它们转换为 JSON。 解决方法是把这个

    静态映射 = { childs lazy: false }

    【讨论】:

    • 在 grails 3.3.8 中不起作用。子项已正确加载到域实例中,但一旦转换为 JSON,它们仍然只显示 id
    【解决方案3】:

    用户 dbrin 是正确的,但还有一个选择。你也可以使用 Grails GSON 插件:

    https://github.com/robfletcher/grails-gson#readme

    插件在处理 json 数据时增加了一些功能。

    【讨论】:

      【解决方案4】:

      建议的解决方案有效,但是我在引用“grailsApplication”时遇到了一些麻烦。事实证明,您可以像任何其他服务一样摄取它。我将以下代码放入

      BootStrap.groovy

      文件。此外,类 DeepDomainClassMarshaller 可以很好地处理双向循环引用,但要注意 JSON 有效负载在深度分离之后不会太大。

      package aisnhwr
      
      import grails.converters.JSON
      import grails.core.GrailsApplication
      import org.grails.web.converters.marshaller.json.DeepDomainClassMarshaller
      
      class BootStrap {
      
          GrailsApplication grailsApplication
      
          def init = { servletContext ->
              JSON.createNamedConfig('deep'){
                  it.registerObjectMarshaller( new DeepDomainClassMarshaller(false, grailsApplication) )
              }
          }
          def destroy = {
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-05-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多