Serialize & Deserialize bean to json with Groovy

自闭症网瘾萝莉.ら 提交于 2019-12-21 17:30:54

问题


I've read this news about json with groovy http://www.infoq.com/news/2014/04/groovy-2.3-json. So I tried to native methods to (de)serialization of groovy bean containing dates. But I have issues whent using JsonOutput.toJson(object) with JsonObject.fromObject() with 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+ ?

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/)

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

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
    }
}

回答1:


Workaround

I found a workaround, but overall the Json (de)serialization is quite messy with dates...

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)

Java 7.0 introduced the ISO 8601 support with "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. Moreover the default JsonSlurper is not converting date by default. Only JsonParserLax and JsonFastParser seems to care about Date parsing, so you need to force the right Parser type.

Current workaround based on 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.

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"

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 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"}

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:
{"name":"John","registration":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:


Work arounds are good. Just want to update I used groovy 2.4.5 and the problem looks to be fixed.

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}


来源:https://stackoverflow.com/questions/27250386/serialize-deserialize-bean-to-json-with-groovy

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!