If you want to generate both XML and JSON views of some object, one option is to use JAXB2 annotations for the XML mapping and Jackson annotations for the JSON mapping. But that’s a little bit of a nuisance, because you have to declare the what are essentially the same mappings twice. It turns out that it’s possible to configure Jackson to use the JAXB2 annotations.
Maven configuration
First, make sure you have the jackson-xc dependency (in addition to the other Jackson dependencies) declared. This is the Maven dependency that supports using JAXB2 annotations:
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-xc</artifactId>
<version>1.9.2</version>
</dependency>
Spring configuration
Next, you’ll need a bit of Spring configuration:
<oxm:jaxb2-marshaller id="marshaller">
<oxm:class-to-be-bound name="org.skydingo.skybase.model.Person" />
<oxm:class-to-be-bound name="org.skydingo.skybase.model.Project" />
</oxm:jaxb2-marshaller>
<bean id="jaxbAnnIntrospector"
class="org.codehaus.jackson.xc.JaxbAnnotationIntrospector" />
<bean id="jacksonObjectMapper" class="org.codehaus.jackson.map.ObjectMapper">
<property name="serializationConfig.annotationIntrospector"
ref="jaxbAnnIntrospector" />
<property name="deserializationConfig.annotationIntrospector"
ref="jaxbAnnIntrospector" />
</bean>
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="mediaTypes">
<map>
<entry key="html" value="text/html" />
<entry key="json" value="application/json" />
<entry key="xml" value="application/xml" />
</map>
</property>
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp" />
</list>
</property>
<property name="defaultViews">
<list>
<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"
p:objectMapper-ref="jacksonObjectMapper">
<property name="renderedAttributes">
<set>
<value>person</value>
<value>project</value>
</set>
</property>
</bean>
<bean class="org.springframework.web.servlet.view.xml.MarshallingView"
p:marshaller-ref="marshaller" />
</list>
</property>
</bean>
Note the use of the compound property names when injecting into the Jackson ObjectMapper. That’s a little-known but useful technique for performing injections in cases where constructor and simple property injection aren’t options.
See also
- http://hillert.blogspot.com/2011/01/marshal-json-data-using-jackson-in.html
- http://wiki.fasterxml.com/JacksonJAXBAnnotations
Pingback: Configuring Jackson to use JAXB2 annotations... | Web Services | Syngu
Pingback: Supporting XML and JSON web service endpoints in Spring 3.1 using @ResponseBody « Spring in Practice