The previous section on on XML and JSON responses covered simplistic examples of rendering XML and JSON responses. Whilst the XML builder used by Grails is the standard XmlSlurper found in Groovy, the JSON builder is a custom implementation specific to Grails.

JSONBuilder and Grails versions

JSONBuilder behaves different depending on the version of Grails you use. For version below 1.2 there deprecated api:grails.util.JSonBuilder class is used. This section covers the usage of the Grails 1.2 JSONBuilder

For backwards compatibility the old JSonBuilder class is used with the render method for older applications, if you want to use the newer/better JSONBuilder class then you can do so by setting the following in Config.groovy:

grails.json.legacy.builder=false

Rendering Simple Objects

To render a simple JSON object just set properties within the context of the closure:

render(contentType:"text/json") {
	hello = "world"
}

The above will produce the JSON:

{"hello":"world"}

Rendering JSON Arrays

To render a list of objects simple assign a list:

render(contentType:"text/json") {
	categories = ['a', 'b', 'c']
}

This will produce:

{"categories":["a","b","c"]}

You can also render lists of complex objects, for example:

render(contentType:"text/json") {
	categories = [ { a = "A" }, { b = "B" } ]
}

This will produce:

{"categories":[ {"a":"A"} , {"b":"B"}] }

If you want to return a list as the root then you have to use the special element method:

render(contentType:"text/json") {
	element 1
	element 2
	element 3		
}

The above code produces:

[1,2,3]

Rendering Complex Objects

Rendering complex objects can be done with closures. For example:

render(contentType:"text/json") {
    categories = ['a', 'b', 'c']
    title ="Hello JSON"
    information = {
        pages = 10
    }
}

The above will produce the JSON:

{"categories":["a","b","c"],"title":"Hello JSON","information":{"pages":10}}

Arrays of Complex Objects

As mentioned previously you can nest complex objects within arrays using closures:

render(contentType:"text/json") {
	categories = [ { a = "A" }, { b = "B" } ]
}

However, if you need to build them up dynamically then you may want to use the array method:

def results = Book.list()
render(contentType:"text/json") {
	books = array {
		for(b in results) {
			book title:b.title
		}
	}	
}

Direct JSONBuilder API Access

If you don't have access to the render method, but still want to produce JSON you can use the API directly:

def builder = new JSONBuilder()

def result = builder.build { categories = ['a', 'b', 'c'] title ="Hello JSON" information = { pages = 10 } }

// prints the JSON text println result.toString()

def sw = new StringWriter() result.render sw