【问题标题】:Serialize & Deserialize bean to json with Groovy使用 Groovy 将 bean 序列化和反序列化为 json
【发布时间】:2015-01-30 18:09:36
【问题描述】:

我已经用 groovy http://www.infoq.com/news/2014/04/groovy-2.3-json 阅读了有关 json 的新闻。 所以我尝试使用本地方法来(反)序列化包含日期的 groovy bean。 但是我在使用 JsonOutput.toJson(object) 和 JsonObject.fromObject() 和 java.util.Date 时遇到问题

String jsonDat a= groovy.json.JsonOutput.toJson(contact)
Contact reloadContact = new Contact(net.sf.json.JSONObject.fromObject(jsonData))

在 groovy 2.3+ 中使用本机方法的正确方法是什么?

否则,我可以去另一个库,例如 gson (http://www.mkyong.com/java/how-do-convert-java-object-to-from-json-format-gson-api/)

package test

import groovy.json.JsonOutput
import net.sf.json.JSONObject

class JsonTest {

    public static void main(String[] args) {
        JsonTest test = new JsonTest()
        test.serialization()
    }

    public void serialization(){
        Contact contact = new Contact()
        contact.name = 'John'
        contact.registration = Date.parse('dd/MM/yyyy', '20/10/2011')

        String jsonData = JsonOutput.toJson(contact)
        println(jsonData)

        Object object = JSONObject.fromObject(jsonData)
        Contact reloadContact = new Contact(object)

        println(jsonData)
    }

    public class Contact{
        String name
        Date registration
    }
}

编辑:我也尝试使用 JsonSlurper,但总是得到 GroovyCastException: Cannot cast object '2011-10-19T22:00:00+0000' with class 'java.lang.String' to class 'java.util.Date ' 封装测试

import groovy.json.JsonOutput
import groovy.json.JsonSlurper

class JsonTest {

    public static void main(String[] args) {
        JsonTest test = new JsonTest()
        test.serialization()
    }

    public void serialization(){
        Contact contact = new Contact()
        contact.name = 'John'
        contact.registration = Date.parse('dd/MM/yyyy', '20/10/2011')

        String jsonData = JsonOutput.toJson(contact)
        println(jsonData)

        JsonSlurper slurper = new JsonSlurper()
        def object = slurper.parseText(jsonData)
        Contact reloadContact = new Contact(object)

        println(jsonData)
    }

    public class Contact{
        String name
        Date registration
    }
}

【问题讨论】:

  • 还显示您的联系人类别和您遇到的问题会有所帮助。甚至更好地提供一个最小的例子,显示问题/异常/...
  • 还尝试使用 Boon: ObjectMapper mapper = JsonFactory.create() 但由于 Groovy 元类,我得到“检测到循环依赖”:s 我必须错过一些东西才能让本机方法工作......跨度>

标签: java json serialization groovy deserialization


【解决方案1】:

解决方法

我找到了一种解决方法,但总体而言,Json(反)序列化的日期非常混乱......

虽然http://groovy-lang.org/json.html 声明对 java.util.date 的支持,但它仍然依赖于“旧”RFC 822“yyyy-MM-dd'T'HH:mm:ssZ”请参阅https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html#timezone(Java 6.0 及更低版本)

Java 7.0 通过“yyyy-MM-dd'T'HH:mm:ss.SSSXXX”引入了 ISO 8601 支持

这个错误http://jira.codehaus.org/browse/GROOVY-6854 仍然存在于 Groovy 2.3.7 中。此外,默认的 JsonSlurper 默认不转换日期。只有 JsonParserLax 和 JsonFastParser 似乎关心 Date 解析,所以你需要强制正确的 Parser 类型。

当前基于 GROOVY-6854 的解决方法:

public void serializationNative(){
    Contact contact = new Contact()
    contact.name = 'John'
    contact.registration = Date.parse('dd/MM/yyyy', '20/10/2011')

    def sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
    sdf.setTimeZone(TimeZone.getTimeZone('UTC'))
    JsonOutput.dateFormatter.set(sdf)
    String jsonData = JsonOutput.toJson(contact)
    println(jsonData)

    JsonSlurper slurper = new JsonSlurper().setType( JsonParserType.INDEX_OVERLAY )
    def object = slurper.parseText(jsonData)
    Contact reloadContact = new Contact(object)
}

我希望 JSON 的(反)序列化约定将在即将发布的版本中强制执行。

为了完整起见,我也尝试了其他库,这里是我的其他测试:

恩惠

Boon 0.30 在序列化 Groovy 对象(元类)时迷失了方向,并为“检测到的循环依赖”抛出 org.boon.Exceptions$SoftenedException

public void serializationBoon(){
    Contact contact = new Contact()
    contact.name = 'John'
    contact.registration = Date.parse('dd/MM/yyyy', '20/10/2011')

    ObjectMapper mapper = JsonFactory.create()

    String jsonData = mapper.toJson(contact)
    println(jsonData)

    Contact reloadContact = mapper.fromJson(jsonData, Contact.class)
}

格森

Gson 2.3.1 works 开箱即用,但序列化为本地日期格式:{"name":"John","re​​gistration":"Oct 20, 2011 12:上午 00:00”}

public void serializationGson(){
    Contact contact = new Contact()
    contact.name = 'John'
    contact.registration = Date.parse('dd/MM/yyyy', '20/10/2011')

    Gson gson = new Gson()

    String jsonData = gson.toJson(contact)
    println(jsonData)

    Contact reloadContact = gson.fromJson(jsonData, Contact.class)

    println(jsonData)
}

杰克逊

Jackson 2.4.4 工作开箱即用,但序列化为纪元毫秒格式:
{"name":"John","re​​gistration":1319061600000}

public void serializationJackson(){
    Contact contact = new Contact()
    contact.name = 'John'
    contact.registration = Date.parse('dd/MM/yyyy', '20/10/2011')

    com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();

    String jsonData = mapper.writeValueAsString(contact)
    println(jsonData)

    Contact reloadContact = mapper.readValue(jsonData, Contact.class)
}

【讨论】:

    【解决方案2】:

    变通方法很好。只是想更新我使用了 groovy 2.4.5,问题看起来已经解决了。

    Book b = new Book(isbn:'dfjkad',quantity: 6, price: 5.00, title: "our mork book",
            publishDate: Date.parse('dd/MM/yyyy', '20/10/2011'), publisher: "matt payne")
    render JsonOutput.toJson(b)
    

    输出

    {"publishDate":"2011-10-20T04:00:00+0000","title":"our mork book","publisher":"matt payne","isbn":"dfjkad","price":5.00,"quantity":6,"author":null}
    

    【讨论】:

      猜你喜欢
      • 2012-09-05
      • 1970-01-01
      • 2020-10-23
      • 1970-01-01
      • 2018-04-09
      • 1970-01-01
      • 2013-04-09
      • 2016-09-15
      • 1970-01-01
      相关资源
      最近更新 更多