简体   繁体   English

使用Groovy将bean序列化和反序列化为json

[英]Serialize & Deserialize bean to json with Groovy

I've read this news about json with groovy http://www.infoq.com/news/2014/04/groovy-2.3-json . 我已经通过groovy http://www.infoq.com/news/2014/04/groovy-2.3-json阅读了有关json的新闻。 So I tried to native methods to (de)serialization of groovy bean containing dates. 所以我尝试了本地方法来(de)序列化包含日期的groovy bean。 But I have issues whent using JsonOutput.toJson(object) with JsonObject.fromObject() with java.util.Date 但我有问题,使用JsonOutput.toJson(对象)与JsonObject.fromObject()与java.util.Date

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

What is the right way to to this with native methods in groovy 2.3+ ? 在groovy 2.3+中使用原生方法的正确方法是什么?

Otherwise, I could go for another library like gson ( http://www.mkyong.com/java/how-do-convert-java-object-to-from-json-format-gson-api/ ) 否则,我可以去另一个像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
    }
}

Edit: I also tried with JsonSlurper, but always get the GroovyCastException: Cannot cast object '2011-10-19T22:00:00+0000' with class 'java.lang.String' to class 'java.util.Date' package test 编辑:我也试过JsonSlurper,但总是得到GroovyCastException:无法将类'java.lang.String'的对象'2011-10-19T22:00:00 + 0000'转换为类'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
    }
}

Workaround 解决方法

I found a workaround, but overall the Json (de)serialization is quite messy with dates... 我找到了一个解决方法,但总体来说Json(de)序列化对日期非常混乱......

While http://groovy-lang.org/json.html states support for java.util.date it still relies on the "old" RFC 822 "yyyy-MM-dd'T'HH:mm:ssZ" see https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html#timezone (Java 6.0 and below) 虽然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 introduced the ISO 8601 support with "yyyy-MM-dd'T'HH:mm:ss.SSSXXX" Java 7.0引入了ISO 8601支持“yyyy-MM-dd'T'HH:mm:ss.SSSXXX”

This bug http://jira.codehaus.org/browse/GROOVY-6854 is still present in Groovy 2.3.7. 这个错误http://jira.codehaus.org/browse/GROOVY-6854仍然存在于Groovy 2.3.7中。 Moreover the default JsonSlurper is not converting date by default. 此外,默认情况下,默认的JsonSlurper不会转换日期。 Only JsonParserLax and JsonFastParser seems to care about Date parsing, so you need to force the right Parser type. 只有JsonParserLax和JsonFastParser似乎关心Date解析,因此您需要强制使用正确的Parser类型。

Current workaround based on GROOVY-6854: 目前基于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)
}

I hope the (de)serialization conventions for JSON will be enforced in upcoming release. 我希望JSON的(反)序列化约定将在即将发布的版本中实施。

For the sake of completeness, I also tried other libraries here are my other tests: 为了完整起见,我还尝试了其他库,这是我的其他测试:

Boon 福利

Boon 0.30 gets lost in serializing Groovy object (metaClass) and throws org.boon.Exceptions$SoftenedException for "Detected circular dependency" Boon 0.30在序列化Groovy对象(metaClass)时丢失,并为“检测到的循环依赖”抛出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 GSON

Gson 2.3.1 works out-of-the-box but serializes to a Local Date format: {"name":"John","registration":"Oct 20, 2011 12:00:00 AM"} GSON 2.3.1 作品外的即装即用,但序列化到本地日期格式:{“名”:“约翰”,“登记”:“2011年10月20日12:00:00 AM”}

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 杰克逊

Jackson 2.4.4 works out-of-the-box but serializes to epoch millisecond format: 杰克逊2.4.4 作品外的即装即用,但序列化为划时代毫秒格式:
{"name":"John","registration":1319061600000} { “名”: “约翰”, “登记”: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)
}

Work arounds are good. 解决方案很好。 Just want to update I used groovy 2.4.5 and the problem looks to be fixed. 只是想更新我使用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)

outputs 输出

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM