java - Grails XML marshalling: change default "<list>" root element name -
by default grails renders list in xml <list>
element tag @ root. likewise renders map <map>
. control name of root element.
if i'm returning arraylist of user, i'd see:
<users> <user>...</user> <user>...</user> </users>
how can achieve above? here requirements:
- easy apply serialization 50+ domain classes
- abstracted developers no explicit coding required during rendering domain objects (i.e., when
render()
orrespond()
invoked, arraylist still passed in, no explicit casting/convertingas mynewtype
) - able handle edge case of empty list (should return
<users/>
)
nice-to-haves:
- if formula can applied map well, great :)
i have been semi-successful in achieving goals above, except don't know how account empty list case. implemented own objectmarshaller renders objects of type list
. long list contains 1 element, can check element's type , determine plural tag name should (user => users). if list empty, , since java generics erasure (unless that's different in groovy?) have no way name empty list other defaulting <list/>
, not acceptable.
some resources i've been through:
- http://www.cacoethes.co.uk/blog/groovyandgrails/dry-json-and-xml-with-grails
- http://grails.1312388.n4.nabble.com/custom-xml-marshaller-change-the-root-element-name-td4649949.html
- http://jwicz.wordpress.com/2011/07/11/grails-custom-xml-marshaller/
- http://mrhaki.blogspot.com/2013/11/grails-goodness-register-custom.html
- http://manbuildswebsite.com/2010/02/15/rendering-json-in-grails-part-3-customise-your-json-with-object-marshallers/
a way achieve write subclass collectionmarshaller class , register in our grails application. can example register custom implementation in bootstrap.groovy following code:
import org.codehaus.groovy.grails.web.converters.marshaller.xml.collectionmarshaller import grails.converters.xml class bootstrap { def init = { servletcontext -> // register custom collection marshaller list user instances. // root element name set users. xml.registerobjectmarshaller(new collectionmarshaller() { @override public boolean supports(object object) { object instanceof list<user> } @override string getelementname(final object o) { 'users' } }) } }
to make work more domain classes might reference domain classes in bootstrap.groovy , loop through them configure custom collectionmarshaller instances.
for maps can extend mapmarshaller
also described in http://mrhaki.blogspot.com/2014/02/grails-goodness-customize-root-element.html
Comments
Post a Comment