views:

659

answers:

5

Hi,

I am working on a REST based interface where people get a json file. The client needs to access the file from another Domain. I use jsonp which works so far. My problem is the rendering in Grails. At the moment I use the 'as JSON' to marshalling the object:

render "${params.jsoncallback}(${user as JSON})"

The Json file getting to the client inclused all attributes, incluing the id and class, which I do not want to have in there. In case it is not jsonp, I do it this way, which works great:

render(contentType:'text/json'){
   userName  user.userName
   userImage user.userImage
    :
    :
}

So how do I get the id and class attributes out of the json when rendering "user as JSON"? Any idea?

best regards, Klaas

A: 

It doesn't seem to me as if the JSON auto marshaller supports this.

You could use FlexJSON which allows you to exlude certain properties and wrap it into a custom Codec. Also see here.

Daff
+1  A: 

You can get rid of the class and id properties in the JSON result by creating a custom ObjectMarshaller.

// CustomDomainMarshaller.groovy in src/groovy:
import grails.converters.JSON;
import org.codehaus.groovy.grails.web.converters.ConverterUtil;
import org.codehaus.groovy.grails.web.converters.exceptions.ConverterException;
import org.codehaus.groovy.grails.web.converters.marshaller.ObjectMarshaller;
import org.codehaus.groovy.grails.web.json.JSONWriter;
import org.springframework.beans.BeanUtils;

public class CustomDomainMarshaller implements ObjectMarshaller<JSON> {

    static EXCLUDED = ['metaClass','class','id','version']

    public boolean supports(Object object) {
        return ConverterUtil.isDomainClass(object.getClass());
    }

    public void marshalObject(Object o, JSON json) throws ConverterException {
        JSONWriter writer = json.getWriter();
        try {
            writer.object();
            def properties = BeanUtils.getPropertyDescriptors(o.getClass());
            for (property in properties) {
                String name = property.getName();
       if(!EXCLUDED.contains(name)) {
                    def readMethod = property.getReadMethod();
                    if (readMethod != null) {
                        def value = readMethod.invoke(o, (Object[]) null);
                        writer.key(name);
                        json.convertAnother(value);
                    }
       }
            }
            writer.endObject();
        } catch (Exception e) {
            throw new ConverterException("Exception in CustomDomainMarshaller", e);
        }
    }
}

You'll need to register in you grails-app/conf/BootStrap.groovy:

class BootStrap {
   def init = { servletContext ->
      grails.converters.JSON.registerObjectMarshaller(new CustomDomainMarshaller())
   }
   def destroy = {}
}

This should work in Grails >= 1.1

Siegfried Puchbauer
A: 

Hi, thanks for the 'quick' reply!

Man, it looks so easy in the end and took so long to figure out. I got it working doing a map out of the values I needed and rendered them 'as json' like this:

def userProfile = user.get(randomUser)

def jsonData = [
username: userProfile.userName,
userimage: userProfile.userImage,
userstreet: userProfile.userStreet,
:
:
] as JSON

println jsonData

voila, there was the json I needed :)

Klaas
A: 

Here is another method: http://foxgem.blogspot.com/2010/06/return-partial-domain-class.html

foxgem
A: 

Please check here to render selective fields in a JSON Response

Amit Jain