10.11.2 Implementing a Custom Renderer 5.2.5

(Quick Reference) # 10.11.2 Implementing a Custom Renderer Version: 5.2.5 ## 10.11.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.MimeType

    class 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"/>
| 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) {
            ....
        }
    }
| Quick Reference (hide)