ylima
ylima

Reputation: 440

How to implement a custom deep ObjectMarshaller<JSON> in Grails?

I'm trying to register a custom JSON marshaller using spring's ObjectMarshallerRegisterer bean as described here.

My intention is to capitalize every property name of all classes that implement a certain interface during the marshalling process.

So far, I've implemented this class which is registered as an object marshaller:

import grails.converters.JSON

import org.codehaus.groovy.grails.web.converters.exceptions.ConverterException;
import org.codehaus.groovy.grails.web.converters.marshaller.ObjectMarshaller;

class MyMarshaller implements ObjectMarshaller<JSON> {

    @Override
    boolean supports(Object object) {
        object instanceof MyInterface
    }

    @Override
    void marshalObject(Object object, JSON json)
            throws ConverterException {
        def jsonWriter = json.writer

        jsonWriter.object()
        object.class.metaClass.properties.each {
            jsonWriter.key(it.name.capitalize())
            def value = object."${it.name}"
            if(value == null || value instanceof Boolean ||
                    value instanceof Number || value instanceof String) {
                jsonWriter.value(value)
            } else {
                // TODO: Fix this
                jsonWriter.value(JSON.parse((value as JSON).toString()))
            }
        }
        jsonWriter.endObject()
    }
}

This class actually works, but I had to insert this line jsonWriter.value(JSON.parse((value as JSON).toString())) as a quick fix.

Well, convert the object to a String and then parse it is not a good strategy. There's gotta be a better way to do it. Can you guys help me?

Thanks.

Upvotes: 2

Views: 621

Answers (1)

ylima
ylima

Reputation: 440

Well, I searched some grails's sources on github to find out how it's done on the default Marshallers. this one gave me the answer:

The line on the code above:

jsonWriter.value(JSON.parse((value as JSON).toString()))

Should be replaced by:

json.convertAnother(value);

Until now it wasn't clear on the docs I found.
Hope this helps someone else with the same issue.

Upvotes: 5

Related Questions