10.11.1 Customizing the Default Renderers

The default renderers for XML and JSON can be found in the grails.rest.render.xml and grails.rest.render.json packages respectively. These use the Grails converters (grails.converters.XML and grails.converters.JSON) by default for response rendering.

You can easily customize response rendering using these default renderers. A common change you may want to make is to include or exclude certain properties from rendering.

Including or Excluding Properties from Rendering

As mentioned previously, Grails maintains a registry of grails.rest.render.Renderer instances. There are some default configured renderers and the ability to register or override renderers for a given domain class or even for a collection of domain classes. To include a particular property from rendering you need to register a custom renderer by defining a bean in grails-app/conf/spring/resources.groovy:

  1. import grails.rest.render.xml.*
  2. beans = {
  3. bookRenderer(XmlRenderer, Book) {
  4. includes = ['title']
  5. }
  6. }
The bean name is not important (Grails will scan the application context for all registered renderer beans), but for organizational and readability purposes it is recommended you name it something meaningful.

To exclude a property, the excludes property of the XmlRenderer class can be used:

  1. import grails.rest.render.xml.*
  2. beans = {
  3. bookRenderer(XmlRenderer, Book) {
  4. excludes = ['isbn']
  5. }
  6. }

Customizing the Converters

As mentioned previously, the default renders use the grails.converters package under the covers. In other words, under the covers they essentially do the following:

  1. import grails.converters.*
  2. ...
  3. render book as XML
  4. // or render book as JSON

Why the separation between converters and renderers? Well a renderer has more flexibility to use whatever rendering technology you chose. When implementing a custom renderer you could use Jackson, Gson or any Java library to implement the renderer. Converters on the other hand are very much tied to Grails' own marshalling implementation.