Tuesday, May 29, 2012

Apache CXF + Jackson

Some days ago I had a task for converting java HashMap to JSON responce, using Apache CXF framework. It was surprise for me that standart CXF JSON provider(Jettison) doesn't work with maps. As I didnt want to write my custom XMLAdapter, I desided to use Jackson, as it works with maps perfectly.

There are next steps to configure:
  1. Add Jackson maven dependency
  2. <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-jaxrs</artifactId>
        <version>1.9.7</version>
    </dependency> 
    

  3. Include Jackson provider bean into your service providers:
  4. <bean id="jsonProvider" class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/>
    <jaxrs:server id="clientService" address="/clientservice">
            <jaxrs:serviceBeans>
                <ref bean="clientBean" />
            </jaxrs:serviceBeans>
            <jaxrs:extensionMappings>
                <entry key="json" value="application/json"/>
                <entry key="xml" value="application/xml"/>
            </jaxrs:extensionMappings> 
            <jaxrs:providers>
                <ref bean="jaxbProvider"/>
            </jaxrs:providers>
     </jaxrs:server>
    
Now all JSON responces from "clientService" are generated by Jackson.
Also next Jackson configuration could be very usefull:
  • Enable wrapping entities with root element.
  • Exclude null values from JSON responce. 
  • This features are disabled by default. To enable it I created my custom ObjectMapper class, that extends from "org.codehaus.jackson.map.ObjectMapper"
    import org.codehaus.jackson.map.ObjectMapper;
    import org.codehaus.jackson.map.SerializationConfig;
    import org.codehaus.jackson.map.annotate.JsonSerialize;
    
    public class CustomObjectMapper extends ObjectMapper{
    
        public CustomObjectMapper() {
        super();
        super.configure(SerializationConfig.Feature.WRAP_ROOT_VALUE, true);
        super.setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);
        }
    
    }
    

    Then added CustomObjectMapper to "jsonProvider" constructor:
    <bean id="jacksonMapper" class="com.xproject.server.util.CustomObjectMapper" />
    <bean id="jaxbProvider" class="org.codehaus.jackson.jaxrs.JacksonJsonProvider">
            <constructor-arg ref="jacksonMapper" />
     </bean>
    

2 comments: