【问题标题】:Convert grails domain object to JSON and manipulate it将 grails 域对象转换为 JSON 并对其进行操作
【发布时间】:2014-01-21 10:43:49
【问题描述】:

我有一个使用def json = object as JSON 转换的grails 对象。转换完成后,我想在 JSON 中再添加一个名为 pin 的属性,如下所示。

[location:[lat:23.03, lon:72.58]]

到目前为止,这样做的唯一方法似乎如下

  1. 使用 grails.converters.json 将 DomainClass 序列化为 JSON
  2. 将 JSON 转换为字符串
  3. 使用第 2 步中的字符串创建 JSONBoject
  4. 添加属性
  5. 将其转换回字符串

还有其他方法可以使用 grails.converters.json 做到这一点吗?我尝试过使用 Gson,但我不想走那条路,因为我遇到了很多循环引用错误

【问题讨论】:

    标签: json grails


    【解决方案1】:

    试试这个:

    domainInstance.properties + [pin: pinInstance] as JSON
    

    【讨论】:

    • 这会添加 pin 作为域实例的一部分吗?
    • 不,不会。但是您真的需要将您的域与其他字段合并吗?如果是这样,也许最好将此字段添加到您的域类中?或者在其中创建一个代理字段,为pin 提供一个getter?
    • 这是我的第一次尝试,我在域类中添加了 lat 和 lon,并创建了 public getPin() { ['location':[lat:lat,lon:lon]] } 方法,但是当我这样做时,object as JSON pin 没有出现在 JSON 的字符串表示中
    • 查看了org.codehaus.groovy.grails.web.converters.marshaller.json.DomainClassMarshaller的源代码,发现只有域类的持久属性被编组为JSON。因此,获取具有自定义结构的 JSON 最直接的方法是创建 Map 并对其进行编组。
    • 有没有办法获取域对象的对应地图?
    【解决方案2】:

    我最近需要做类似的事情。一些警告:

    • 这是使用 Grails 2.4.5
    • 我使用 MongoDB 作为后端。因此,我为 MongoDB 域类创建了一个对象编组器。它打印在下面,您可以为您的域类包装一个类似的编组器:

    编组器:

    class MongodbObjectMarshaller implements ObjectMarshaller<JSON> {
        @Override
        boolean supports(Object o) { return o?.properties?.dbo }
    
        @Override
        void marshalObject(Object obj, JSON converter) throws    
        ConverterException {
    
            Map propertiesToOutput = obj.properties.dbo
    
            propertiesToOutput.remove("_id")  //don't print org.bson.types.ObjectId
            propertiesToOutput.remove("version")  //don't print gorm verson column
    
            converter.build {
                _id obj.id.toString()
                propertiesToOutput.each{ entry ->
                    "$entry.key" entry.value
                }
            }
    
        }
    }
    

    编组器所做的是,它允许在 JSON 输出中输出任何域类的属性。 obj.properties.dbo 是 MongoDB 特有的,但是对于常规的域类,您可以只获取属性并排除不需要的属性。

    然后在我的控制器中,这可以工作:

    domainInstance.pin = [location:[lat:23.03, lon:72.58]]
    def content = tacticalCard as JSON
    

    因为我的 marshaller 现在拾取 pin 属性并打印它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-24
      • 2012-10-25
      相关资源
      最近更新 更多