JSON is a user-friendly format for structuring data into text format. This text can be easily sent to and from a server. Grails framework provides us with an efficient way to convert domain objects, lists, arrays and other different types of objects to JSON Objects, JSON Converter.
Class :
1 |
grails.converters.JSON |
JSON Converter is explained with the help of an example :
Domain :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
class Parent { String name static hasMany = [children: Child] static constraints = { } } class Child { String name static belongsTo = [parent: Parent] static constraints = { } } |
Call in Controller :
1 2 |
def parent = Parent.list //fetch all the parents from the domain render parent as JSON //convert the list into JSON using default method |
Response :
1 2 3 4 5 6 7 8 9 10 11 12 13 |
[ { "class": "Parent", "id": 1, "name": "parent name", "childs": [ { "class": "Child", "id": 1 } ] } ] |
However, there is a problem with JSON Converter. It reads only the root class objects and not the objects in it’s associated classes. If we require those objects too, like this :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
[ { "class": "Parent", "id": 1, "name": "parent name", "children": [ { "class": "Child", "id": 1, "name": "first child" } ] } ] |
We need to use either of the following methods :
1. Default – all fields, shallow associations
1 |
render parent as JSON |
2. Global deep converter – change all JSON converters to use deep association traversal
1 |
grails.converters.json.default.deep = true //in Config.Groovy |
3. Named config marshaller using provided
1 2 3 |
JSON.createNamedConfig('deep'){ it.registerObjectMarshaller( new DeepDomainClassMarshaller(...) ) } |
4. Custom Converter
1 2 3 |
JSON.use('deep'){ render parent as JSON } |
5. Custom Class specific closure marshaller
1 2 3 4 |
JSON.registerObjectMarshaller(Parent){ return map of properties } render parent as JSON |
6. Custom controller based closure to generate a map of properties
1 2 3 4 |
def convert(object){ return map of properties } render convert(parent) as JSON |
JSON Converter uses option 1 has default. The simplest method is to set global deep converter by adding the mentioned code in Option 2 into the Config.Groovy, but keep in mind that this effects all the JSON Converters in your application, which means that if you have a large amount of associations in the top level object and you try to convert a list of those top level objects, the deep converter will fetch all of the associated objects with the top level object. Using option 4 is the easiest way to get all the associated objects in a specific method instead of using the deep converter globally!
Informative…