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
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:
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:
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