开发者

Grails: JSONP callback without id and class in JSON file

开发者 https://www.devze.com 2022-12-10 17:54 出处:网络
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

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


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


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 :)


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消