Serialize & Deserialize bean to json with Groovy

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