Search

Dark theme | Light theme

February 17, 2017

Groovy Goodness: Creating Root JSON Array With JsonBuilder

To create JSON output with Groovy is easy using JsonBuilder and StreamingJsonBuilder. In the samples mentioned in the links we create a JSON object with a key and values. But what if we want to create JSON with a root JSON array using JsonBuilder or StreamingJsonBuilder? It turns out to be very simple by passing a list of values using the constructor or using the implicit method call.

In the following example we use JsonBuilder to create a root JSON array:

import groovy.json.JsonBuilder

// Example class.
@groovy.transform.Immutable
class Villain { 
    String name 
}

// A list of Villain objects that needs to transformed
// to a JSON array.
def list = ['The Joker', 'Penguin', 'Catwoman', 'Harley Quinn'].collect { name -> new Villain(name) }

// We create a new JsonBuilder and 
// use the list of Villain objects
// as argument for the constructor
// to create a root JSON array.
def json1 = new JsonBuilder(list)

assert json1.toString() == '[{"name":"The Joker"},{"name":"Penguin"},{"name":"Catwoman"},{"name":"Harley Quinn"}]'


// Here we use the no-argument constructor
// to create a JsonBuilder.
// Then we use the instance implicit
// method call with the list of Villain
// objects as arguments
def json2 = new JsonBuilder()
json2(list)

assert json2.toString() == '[{"name":"The Joker"},{"name":"Penguin"},{"name":"Catwoman"},{"name":"Harley Quinn"}]'

In the next example we use StreamingJsonBuilder to create a root JSON array:

import groovy.json.StreamingJsonBuilder

// Example class.
@groovy.transform.Immutable
class Villain { 
    String name 
}

// A list of Villain objects that needs to transformed
// to a JSON array.
def list = ['The Joker', 'Penguin', 'Catwoman', 'Harley Quinn'].collect { name -> new Villain(name) }

// Here we use the no-argument constructor
// to create a JsonBuilder.
// Then we use the instance implicit
// method call with the list of Villain
// objects as arguments
def json = new StringWriter()
def jsonBuilder = new StreamingJsonBuilder(json)
jsonBuilder(list)

assert json.toString() == '[{"name":"The Joker"},{"name":"Penguin"},{"name":"Catwoman"},{"name":"Harley Quinn"}]'

There is also an implicit method call that takes an extra Closure argument. For each element in the list the Closure is invoked with the element as argument. This way we can customize the root JSON array output using the properties of the object that is in the list. In the following example we use both the JsonBuilder and StreamingJsonBuilder classes to transform the elements in the list:

import groovy.json.JsonBuilder
import groovy.json.StreamingJsonBuilder

// Example class.
@groovy.transform.Immutable
class Villain { 
    String name 
}

// A list of Villain objects that needs to transformed
// to a JSON array.
def list = ['The Joker', 'Penguin', 'Catwoman', 'Harley Quinn'].collect { name -> new Villain(name) }

// We create a new JsonBuilder and 
// then we use the instance implicit
// method call with the list of Villain
// objects as arguments and closure
// to transform each Villain object
// in the root JSON array.
def json1 = new JsonBuilder() 
json1(list) { Villain villain ->
    name villain.name
    initials villain.name.split(' ').collect { it[0].toUpperCase() }.join()
}

assert json1.toString() == '[{"name":"The Joker","initials":"TJ"},{"name":"Penguin","initials":"P"},{"name":"Catwoman","initials":"C"},{"name":"Harley Quinn","initials":"HQ"}]'


// We can use the same implicit
// method call for a list and 
// closure to transform each element
// to a root JSON array.
def json = new StringWriter()
def json2 = new StreamingJsonBuilder(json)
json2(list) { Villain villain -> 
    name villain.name
    initials villain.name.split(' ').collect { it[0].toUpperCase() }.join()
}

assert json.toString() == '[{"name":"The Joker","initials":"TJ"},{"name":"Penguin","initials":"P"},{"name":"Catwoman","initials":"C"},{"name":"Harley Quinn","initials":"HQ"}]'

Written with Groovy 2.4.8