|
Hi,
I'm using Grails 2.0.4. I'm trying to remove the 'class' attributes from marshalled JSON responses. I've copied and renamed the Grails GroovyBeenMarshaller: package liftyourgame.grails import grails.converters.JSON; import groovy.lang.GroovyObject; import java.beans.PropertyDescriptor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; 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 NoClassNameObjectMarshaller implements ObjectMarshaller<JSON> { public boolean supports(Object object) { return object instanceof GroovyObject; } public void marshalObject(Object o, JSON json) throws ConverterException { JSONWriter writer = json.getWriter(); try { writer.object(); for (PropertyDescriptor property : BeanUtils.getPropertyDescriptors(o.getClass())) { String name = property.getName(); Method readMethod = property.getReadMethod(); if (readMethod != null && !(name.equals("metaClass"))) { Object value = readMethod.invoke(o, (Object[]) null); writer.key(name); json.convertAnother(value); } } for (Field field : o.getClass().getDeclaredFields()) { int modifiers = field.getModifiers(); if (Modifier.isPublic(modifiers) && !(Modifier.isStatic(modifiers) || Modifier.isTransient(modifiers))) { writer.key(field.getName()); json.convertAnother(field.get(o)); } } writer.endObject(); } catch (ConverterException ce) { throw ce; } catch (Exception e) { throw new ConverterException("Error converting Bean with class " + o.getClass().getName(), e); } } } I was just going to get this working before I add in the !name.equals("class") bit. If I register my converter in Bootstrap init with: JSON.registerObjectMarshaller(new NoClassNameObjectMarshaller()) I get the following error when Marshalling occurs: | Error 2012-06-26 09:44:11,771 [http-bio-8080-exec-9] ERROR errors.GrailsExceptionResolver - IllegalAccessException occurred when processing request: [GET] /liftyourgame/quote Class org.codehaus.groovy.grails.web.converters.marshaller.json.GenericJavaBeanMarshaller can not access a member of class org.springframework.beans.GenericTypeAwarePropertyDescriptor with modifiers "public". Stacktrace follows: Message: Class org.codehaus.groovy.grails.web.converters.marshaller.json.GenericJavaBeanMarshaller can not access a member of class org.springframework.beans.GenericTypeAwarePropertyDescriptor with modifiers "public" Line | Method ->> 199 | value in grails.converters.JSON - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 162 | convertAnother in '' | 199 | value . . . . . in '' | 162 | convertAnother in '' | 199 | value . . . . . in '' | 162 | convertAnother in '' | 32 | marshalObject . in liftyourgame.grails.NoClassNameObjectMarshaller | 199 | value in grails.converters.JSON | 162 | convertAnother . in '' | 32 | marshalObject in liftyourgame.grails.NoClassNameObjectMarshaller | 199 | value . . . . . in grails.converters.JSON | 134 | render in '' | 150 | render . . . . . in '' | 13 | show in liftyourgame.grails.QuoteController | 55 | doFilter . . . . in org.apache.shiro.grails.SavedRequestFilter | 449 | executeChain in org.apache.shiro.web.servlet.AbstractShiroFilter | 365 | call . . . . . . in org.apache.shiro.web.servlet.AbstractShiroFilter$1 | 90 | doCall in org.apache.shiro.subject.support.SubjectCallable | 83 | call . . . . . . in '' | 380 | execute in org.apache.shiro.subject.support.DelegatingSubject | 362 | doFilterInternal in org.apache.shiro.web.servlet.AbstractShiroFilter | 125 | doFilter in org.apache.shiro.web.servlet.OncePerRequestFilter | 1110 | runWorker . . . in java.util.concurrent.ThreadPoolExecutor | 603 | run in java.util.concurrent.ThreadPoolExecutor$Worker ^ 722 | run . . . . . . in java.lang.Thread Any ideas please? Regards, Greg --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
I'm *less* than happy about this solution but it does allow you to
remove unnecessary properties from being marshed. // Move to json converter private excludedProperties = ['class', 'metaClass', 'dateOfBirth', 'dateOfDeath'] private String toJson(Person person) { JSONBuilder builder = new JSONBuilder() return builder.build { person.properties.each {propName, propValue -> if (!(propName in excludedProperties)) { setProperty(propName, propValue) } } setProperty("personId", person.id) setProperty("dateOfBirth", person.dateOfBirth.format("yyyy-MM-dd")) setProperty("dateOfDeath", person.dateOfDeath.format("yyyy-MM-dd")) } } On Tue, Jun 26, 2012 at 12:45 AM, Greg Pagendam-Turner <[hidden email]> wrote: > Hi, > > I'm using Grails 2.0.4. I'm trying to remove the 'class' attributes from > marshalled JSON responses. > > I've copied and renamed the Grails GroovyBeenMarshaller: > > package liftyourgame.grails > > import grails.converters.JSON; > import groovy.lang.GroovyObject; > > import java.beans.PropertyDescriptor; > import java.lang.reflect.Field; > import java.lang.reflect.Method; > import java.lang.reflect.Modifier; > > 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 NoClassNameObjectMarshaller implements ObjectMarshaller<JSON> { > > public boolean supports(Object object) { > return object instanceof GroovyObject; > } > > public void marshalObject(Object o, JSON json) throws ConverterException > { > JSONWriter writer = json.getWriter(); > try { > writer.object(); > for (PropertyDescriptor property : > BeanUtils.getPropertyDescriptors(o.getClass())) { > String name = property.getName(); > Method readMethod = property.getReadMethod(); > if (readMethod != null && !(name.equals("metaClass"))) { > Object value = readMethod.invoke(o, (Object[]) null); > writer.key(name); > json.convertAnother(value); > } > } > for (Field field : o.getClass().getDeclaredFields()) { > int modifiers = field.getModifiers(); > if (Modifier.isPublic(modifiers) && > !(Modifier.isStatic(modifiers) || Modifier.isTransient(modifiers))) { > writer.key(field.getName()); > json.convertAnother(field.get(o)); > } > } > writer.endObject(); > } > catch (ConverterException ce) { > throw ce; > } > catch (Exception e) { > throw new ConverterException("Error converting Bean with class " > + o.getClass().getName(), e); > } > } > } > > I was just going to get this working before I add in the > !name.equals("class") bit. > > If I register my converter in Bootstrap init with: > JSON.registerObjectMarshaller(new NoClassNameObjectMarshaller()) > > I get the following error when Marshalling occurs: > | Error 2012-06-26 09:44:11,771 [http-bio-8080-exec-9] ERROR > errors.GrailsExceptionResolver - IllegalAccessException occurred when > processing request: [GET] /liftyourgame/quote > Class > org.codehaus.groovy.grails.web.converters.marshaller.json.GenericJavaBeanMarshaller > can not access a member of class > org.springframework.beans.GenericTypeAwarePropertyDescriptor with modifiers > "public". Stacktrace follows: > Message: Class > org.codehaus.groovy.grails.web.converters.marshaller.json.GenericJavaBeanMarshaller > can not access a member of class > org.springframework.beans.GenericTypeAwarePropertyDescriptor with modifiers > "public" > Line | Method > ->> 199 | value in grails.converters.JSON > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - > | 162 | convertAnother in '' > | 199 | value . . . . . in '' > | 162 | convertAnother in '' > | 199 | value . . . . . in '' > | 162 | convertAnother in '' > | 32 | marshalObject . in > liftyourgame.grails.NoClassNameObjectMarshaller > | 199 | value in grails.converters.JSON > | 162 | convertAnother . in '' > | 32 | marshalObject in > liftyourgame.grails.NoClassNameObjectMarshaller > | 199 | value . . . . . in grails.converters.JSON > | 134 | render in '' > | 150 | render . . . . . in '' > | 13 | show in liftyourgame.grails.QuoteController > | 55 | doFilter . . . . in org.apache.shiro.grails.SavedRequestFilter > | 449 | executeChain in > org.apache.shiro.web.servlet.AbstractShiroFilter > | 365 | call . . . . . . in > org.apache.shiro.web.servlet.AbstractShiroFilter$1 > | 90 | doCall in > org.apache.shiro.subject.support.SubjectCallable > | 83 | call . . . . . . in '' > | 380 | execute in > org.apache.shiro.subject.support.DelegatingSubject > | 362 | doFilterInternal in > org.apache.shiro.web.servlet.AbstractShiroFilter > | 125 | doFilter in > org.apache.shiro.web.servlet.OncePerRequestFilter > | 1110 | runWorker . . . in java.util.concurrent.ThreadPoolExecutor > | 603 | run in > java.util.concurrent.ThreadPoolExecutor$Worker > ^ 722 | run . . . . . . in java.lang.Thread > > > > Any ideas please? > > Regards, > > Greg > > > > > --------------------------------------------------------------------- > To unsubscribe from this list, please visit: > > http://xircles.codehaus.org/manage_email > > --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
In reply to this post by Greg Pagendam-Turner
Hi Greg, have you solved this? I have the same issue, trying to marshall a command bean using my custom Groovy Marshaller.
|
|
We have faced the same problem after migrating our application from Grails 1.3.7 to 2.0.4.
We had a custom marshaller which used to exclude 'class' property from being visible in JSON. The error occured with classes which had @Validateable annotation on them. This annotation not only adds a validate() method to the class but also introduces a property called 'errors'. While using Grails 1.3.7 this property was not visible in the final json even though we had no config to exclude it explicitly. Once we upgraded to 2.0.4, marshalling an object with @Validateable started to result in exactly the same exception as Greg has mentioned in his post. We traced that it happens when converting 'errors' property. Luckily for us, we didn't need this property in the json. Hence, we excluded 'errors' property in our marshaller and exception disappeared. Sergio, since you domain objects have the same 'errors' property as @Validateable objects, you could also try to exclude it from marshalling, if this is acceptable for you. |
|
With this, the errors goes away, and also you have the option of register custom adapters for custom user types. --
Sérgio Michels On Fri, Mar 29, 2013 at 2:25 PM, kuras [via Grails] <[hidden email]> wrote: We have faced the same problem after migrating our application from Grails 1.3.7 to 2.0.4. |
| Powered by Nabble | Edit this page |
