Search

Dark theme | Light theme

November 21, 2013

Grails Goodness: Register Custom Marshaller Using ObjectMarshallerRegisterer

When we convert data to JSON or XML (or any other format actually) in our Grails application we can register custom marshallers. These marshallers must contain the logic to convert an input object to a given format. For example we could have a book class and we want to convert it to our own JSON format. We have different options in Grails to achieve this, but for now we will create a custom marshaller class CustomBookMarshaller. This class must implement the ObjectMarshaller<C> interface. The generic type is the converter the marshaller is for and is in most cases either grails.converters.XML or grails.converters.JSON. Next we must make sure Grails uses our custom marshaller and we must register it. In the Grails documentation is explained how to do this via grails-app/conf/Bootstrap.groovy where we invoke for example JSON.registerMarshaller(new CustomBookMarshaller()). Or via grails-app/conf/spring/resources.groovy where we must write an extra component with a method annotated @PostConstruct where JSON.registerMarshaller(new CustomBookMarshaller()) is invoked.

But there is also another way using org.codehaus.groovy.grails.web.converters.configuration.ObjectMarshallerRegisterer. This is a Spring bean just for configuring extra marshallers. The bean has a priority property we can use to define the priority for this marshaller. Grails will use a marshaller with the highest priority if for the same class multiple marshallers are defined. We can assign a marshaller to the marshaller property. And finally we must set the converter class, for example grails.converters.XML or grails.converters.JSON with the converter property.

In our grails-app/conf/spring/resources.groovy file we define a new instance of ObjectMarshallerRegisterer and assign the appropriate property values. The name of the bean in resources.groovy is not important, but we must make sure there is no name class with other Spring configured beans. Grails looks for all beans of type ObjectMarshallerRegisterer during marshaller configuration and use the information we provide.

// File: grails-app/conf/spring/resources.groovy
import com.mrhaki.json.CustomBookMarshaller
import grails.converters.JSON
import org.codehaus.groovy.grails.web.converters.configuration.ObjectMarshallerRegisterer

beans = {

    // The name is not important. The type is picked up 
    // by Grails and must be ObjectMarshallerRegisterer.
    customBookJsonMarshaller(ObjectMarshallerRegisterer) {
        // Assign custom marshaller instance.
        marshaller = new CustomBookMarshaller()

        // Set converter class type.
        converterClass = JSON

        // Optional set priority. Default value is 0.
        priority = 1
    }

}

Code written with Grails 2.3.2