Serializing and deserializing a bean to json with Groovy

I was reading this news about json from groovy http://www.infoq.com/news/2014/04/groovy-2.3-json . So I tried to use native methods to (de) serialize groovy bean containing dates. But I am having problems when I use 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's the correct way to do 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 GroovyCastException: Cannot cast object '2011-10-19T22: 00: 00 + 0000' with class 'java.lang.String' into class 'java.util.Date' batch 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
    }
}

      

+3


source to share


2 answers


Bypass

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

While http://groovy-lang.org/json.html claims to support java.util.date, it still relies on the "old" 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 and below)

Java 7.0 introduced 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. Also, by default, JsonSlurper does not convert date by default. Only JsonParserLax and JsonFastParser seem to care about parsing the Date, so you need to force the correct 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 serialization conventions (de) for JSON will be applied in an upcoming release.

For completeness, I've also tried other libraries, here are my other tests:



Boon

Boon 0.30 gets lost while serializing Groovy object (metaClass) and throws org.boon.Exceptions $ SoftenedException for "Circular Dependency Detected"

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 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 milliseconds:
{"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)
}

      

+3


source


The work around is good. Just want to update, I was using groovy 2.4.5 and the problem looks 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}

      

Matt

0


source







All Articles