1. Introduction
In this article, we’re going to describe and see examples of how to work with JSON in a Groovy application.
First of all, to get the examples of this article up and running, we need to set up our pom.xml:
<build>
<plugins>
// ...
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
</build>
<dependencies>
// ...
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>4.0.21</version>
</dependency>
</dependencies>
The most recent Maven plugin can be found here and the latest version of the groovy-all here.
2. Parsing Groovy Objects to JSON
Converting Objects to JSON in Groovy is pretty simple, let’s assume we have an Account class:
class Account {
String id
BigDecimal value
Date createdAt
}
To convert an instance of that class to a JSON String, we need to use the JsonOutput class and make a call to the static method toJson():
Account account = new Account(
id: '123',
value: 15.6,
createdAt: new SimpleDateFormat('MM/dd/yyyy').parse('01/01/2018')
)
println JsonOutput.toJson(account)
As a result, we’ll get the parsed JSON String:
{"value":15.6,"createdAt":"2018-01-01T02:00:00+0000","id":"123"}
2.1. Customizing the JSON Output
As we can see, the date output isn’t what we wanted. For that purpose, starting with version 2.5, the package groovy.json comes with a dedicated set of tools.
With the JsonGenerator class, we can define options to the JSON output:
JsonGenerator generator = new JsonGenerator.Options()
.dateFormat('MM/dd/yyyy')
.excludeFieldsByName('value')
.build()
println generator.toJson(account)
As a result, we’ll get the formatted JSON without the value field we excluded and with the formatted date:
{"createdAt":"01/01/2018","id":"123"}
2.2. Formatting the JSON Output
With the methods above we saw that the JSON output was always in a single line, and it can get confusing if a more complex object has to be dealt with.
However, we can format our output using the prettyPrint method:
String json = generator.toJson(account)
println JsonOutput.prettyPrint(json)
And we get the formatted JSON bellow:
{
"value": 15.6,
"createdAt": "01/01/2018",
"id": "123"
}
3. Parsing JSON to Groovy Objects
We’re going to use Groovy class JsonSlurper to convert from JSON to Objects.
Also, with JsonSlurper we have a bunch of overloaded parse methods and a few specific methods like parseText, parseFile, and others.
We’ll use the parseText to parse a String to an Account class:
def jsonSlurper = new JsonSlurper()
def account = jsonSlurper.parseText('{"id":"123", "value":15.6 }') as Account
In the above code, we have a method that receives a JSON String and returns an Account object, which can be any Groovy Object.
Also, we can parse a JSON String to a Map, calling it without any cast, and with the Groovy dynamic typing, we can have the same as the object.
3.1. Parsing JSON Input
The default parser implementation for JsonSlurper is JsonParserType.CHAR_BUFFER, but in some cases, we’ll need to deal with a parsing problem.
Let’s look at an example for this: given a JSON String with a date property, JsonSlurper will not correctly create the Object because it will try to parse the date as String:
def jsonSlurper = new JsonSlurper()
def account
= jsonSlurper.parseText('{"id":"123","createdAt":"2018-01-01T02:00:00+0000"}') as Account
As a result, the code above will return an Account object with all properties containing null values.
To resolve that problem, we can use the JsonParserType.INDEX_OVERLAY.
As a result, it will try as hard as possible to avoid creation of String or char arrays:
def jsonSlurper = new JsonSlurper(type: JsonParserType.INDEX_OVERLAY)
def account
= jsonSlurper.parseText('{"id":"123","createdAt":"2018-01-01T02:00:00+0000"}') as Account
Now, the code above will return an Account instance appropriately created.
3.2. Parser Variants
Also, inside the JsonParserType, we have some other implementations:
- JsonParserType.LAX will allow a more relaxed JSON parsing, with comments, no quote strings, etc.
- JsonParserType.CHARACTER_SOURCE is used for large file parsing.
4. Conclusion
We’ve covered a lot of the JSON processing in a Groovy application with a couple of simple examples.
For more information about the groovy.json package classes we can have a look at the Groovy Documentation.
Check the source code of the classes used in this article, as well as some unit tests, in our GitHub repository.