how to register a custom json marshaller in grails
Solution 1
this is what i do for custom JSON marshaling in the Bootstrap init closure:
def init = {servletContext ->
grailsApplication.domainClasses.each {domainClass ->
domainClass.metaClass.part = {m ->
def map = [:]
if (m.'include') {
m.'include'.each {
map[it] = delegate."${it}"
}
} else if (m.'except') {
m.'except'.addAll excludedProps
def props = domainClass.persistentProperties.findAll {
!(it.name in m.'except')
}
props.each {
map['id'] = delegate.id
map[it.name] = delegate."${it.name}"
}
}
return map
}
}
JSON.registerObjectMarshaller(Date) {
return it?.format("dd.MM.yyyy")
}
JSON.registerObjectMarshaller(User) {
def returnArray = [:]
returnArray['username'] = it.username
returnArray['userRealName'] = it.userRealName
returnArray['email'] = it.email
return returnArray
}
JSON.registerObjectMarshaller(Role) {
def returnArray = [:]
returnArray['authority'] = it.authority
return returnArray
}
JSON.registerObjectMarshaller(Person) {
return it.part(except: ['fieldX', 'fieldY'])
}}
you see that i have custom marshallers for the Date, Use, Person, and Role Class
Solution 2
I found this post while trying to find out a proper way for the marshaller registering. The biggest difference compared to Nils' answer is that this solution leaves BootStrap.groovy intact, which is nice.
http://compiledammit.com/2012/08/16/custom-json-marshalling-in-grails-done-right/
vijay tyagi
Updated on June 30, 2022Comments
-
vijay tyagi almost 2 years
I am trying to register a custom json marshaller like this
JSON.createNamedConfig("dynamic",{ def m = new CustomJSONSerializer() JSON.registerObjectMarshaller(Idf, 1, { instance, converter -> m.marshalObject(instance, converter) }) }) and then using it like this JSON.use("dynamic"){ render inventionList as JSON }
but I am not sure if my custom serializer is being used because when I am debugging control never goes to
marshalObject
function of my custom serializerMy custom serializer is as follows
import grails.converters.deep.JSON import java.beans.PropertyDescriptor import java.lang.reflect.Field import java.lang.reflect.Method import org.codehaus.groovy.grails.web.converters.exceptions.ConverterException import org.codehaus.groovy.grails.web.converters.marshaller.json.GroovyBeanMarshaller import org.codehaus.groovy.grails.web.json.JSONWriter class CustomJSONSerializer extends GroovyBeanMarshaller{ public boolean supports(Object object) { return object instanceof GroovyObject; } public void marshalObject(Object o, JSON json) throws ConverterException { JSONWriter writer = json.getWriter(); println 'properties '+BeanUtils.getPropertyDescriptors(o.getClass()) for(PropertyDescriptor property:BeanUtils.getProperyDescriptors(o.getClass())){ println 'property '+property.getName() } try { writer.object(); for (PropertyDescriptor property : BeanUtils.getPropertyDescriptors(o.getClass())) { String name = property.getName(); Method readMethod = property.getReadMethod(); if (readMethod != null && !(name.equals("metaClass")) && readMethod.getName()!='getSpringSecurityService') { 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); } } }
Is it possible to debug the serializer? If not then how can I exclude a property from serialization? There's some property which throws exception during serialization.
-
cdeszaq over 11 yearsThe article you linked to is a much better, cleaner approach. To help deal with link rot, please consider quoting the most relevant bits of the article here in your answer.
-
adeady about 7 yearssite appears to be down these days.