10.1.9 Customizing Response Rendering 3.1.1

See the light - agile, industrial strength, rapid web application development made easy

(Quick Reference) # 10.1.9 Customizing Response Rendering - Reference Documentation Authors: Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith, Lari Hotari Version: 3.1.1 ## Table of Contents ## 10.1.9 Customizing Response Rendering If you are looking for a more low-level API and JSON or Markup views don't suite your needs then you may want to consider implementing a custom renderer. ## 10.1.9.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`:

    import grails.rest.render.xml.*beans = {
        bookRenderer(XmlRenderer, Book) {
            includes = ['title']
        }
    }
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:

    import grails.rest.render.xml.*beans = {
        bookRenderer(XmlRenderer, Book) {
            excludes = ['isbn']
        }
    }
#### 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:

    import grails.converters.*…
    render book as XML// 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. ## 10.1.9.2 Implementing a Custom Renderer If you want even more control of the rendering or prefer to use your own marshalling techniques then you can implement your own `Renderer` instance. For example below is a simple implementation that customizes the rendering of the `Book` class:

    package myapp
    import grails.rest.render.*
    import grails.web.mime.MimeTypeclass BookXmlRenderer extends AbstractRenderer<Book> {
        BookXmlRenderer() {
            super(Book, [MimeType.XML,MimeType.TEXT_XML] as MimeType[])
        }    void render(Book object, RenderContext context) {
            context.contentType = MimeType.XML.name        def xml = new groovy.xml.MarkupBuilder(context.writer)
            xml.book(id: object.id, title:object.title)
        }
    }
The `AbstractRenderer` super class has a constructor that takes the class that it renders and the `MimeType`(s) that are accepted (via the ACCEPT header or file extension) for the renderer. To configure this renderer, simply add it is a bean to `grails-app/conf/spring/resources.groovy`:
    beans = {
        bookRenderer(myapp.BookXmlRenderer)
    }
The result will be that all `Book` instances will be rendered in the following format:
    <book id="1" title="The Stand"/>
Note that if you change the rendering to a completely different format like the above, then you also need to change the binding if you plan to support POST and PUT requests. Grails will not automatically know how to bind data from a custom XML format to a domain class otherwise. See the section on "Customizing Binding of Resources" for further information. #### Container Renderers A `grails.rest.render.ContainerRenderer` is a renderer that renders responses for containers of objects (lists, maps, collections etc.). The interface is largely the same as the `Renderer` interface except for the addition of the `getComponentType()` method, which should return the "contained" type. For example:
    class BookListRenderer implements ContainerRenderer<List, Book> {
        Class<List> getTargetType() { List }
        Class<Book> getComponentType() { Book }
        MimeType[] getMimeTypes() { [ MimeType.XML] as MimeType[] }
        void render(List object, RenderContext context) {
            ....
        }
    }
## 10.1.9.3 Using GSP to Customize Rendering You can also customize rendering on a per action basis using Groovy Server Pages (GSP). For example given the `show` action mentioned previously:
    def show(Book book) {
        respond book
    }
You could supply a `show.xml.gsp` file to customize the rendering of the XML:
    <%@page contentType="application/xml"%>
    <book id="${book.id}" title="${book.title}"/>
| Quick Reference (hide)