Serialize & Deserialize bean to json with Groovy
Solution 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)
}
Solution 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}
Wavyx
Updated on June 07, 2022Comments
-
Wavyx almost 2 years
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 } }