Json – Spring 3.1 custom JSON converters

jacksonjsonspring-mvc

Im using Spring MVC 3.1 which by default uses Jackson for JSON-Java conversions.

I need to create custom conversions for the following:

  1. java.util.List (for all sorts of different types).
  2. Enums to strings
  3. java.util.Calendar

I have encountered a few different approaches for creating my custom converters:

  1. As described here more or less, create a custom ObjectMapper:

    public class CustomObjectMapper extends ObjectMapper…

Then adding MappingJacksonHttpMessageConverter to my servlet-context and register it with my custom ObjectMapper:

Then i guess I need to have some specific implementations in my custom objectMapper (how should it look like?).

  1. A second approach talks about extending FormattingConversionServiceFactoryBean and create my own converters (a class that implements org.springframework.core.convert.converter.Converter) as described here.

UPDATE 1:
Another approach I have seen is to subcalss MappingJacksonHttpMessageConverter and override getJavaType method, as described here. To do this I will have to add my custom converter to the list of converters:

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
    <list>
        <bean class="com.yl.app.CustomMappingJacksonHttpMessageConverter">
    </list>
</property>

Which approach is the recommended one? Are these the only ones, is there a better way of doing it?

UPDATE 2:

I still don't get it. In practice, suppose I have class A and class B.

Class A holds a list of B:

public class A {

   public List<B> list;

}

I would like to return an object of type A to my client. What should I do in my server besides adding the @ResponseBody annotation (which is not enough in this case as far as I get it)?

Best Answer

Both approaches serve different purposes:

The first approach that you have outlined is to customize Jackson ObjectMapper - say for eg, to show the date in a different format in the json or to register a custom serializer to handle mapping a class to a json a little differently.

The second approach is to register converters - to transform one object to another, say for eg, to convert a String request parameter from the UI to an object or say if you get the entity id of a field and want to convert it to an entity.

So both have their place, to customize Jackson you would use the first approach, to create custom converters you would use the second approach.

Update: Based on the new information that you have provided, I think what you are looking for is actually a HttpMessageConverter not a Converter.

When you say you want to return an object of type A to your client, you would serialize it some way over the wire - json or xml typically, but potentially other formats also - if you are going to convert it to json then you essentially customize ObjectMapper underlying MappingJacksonHttpMessageConverter(with Jackson 1.x) or MappingJackson2HttpMessageConverter(with Jackson2.x) you would typically do this:

<mvc:annotation-driven conversion-service="conversionService"> 
   <mvc:message-converters register-defaults="true">
       <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
           <property name="objectMapper">
               <bean class="org.bk.lmt.web.spring.CustomObjectMapper"/>
           </property>
       </bean>
   </mvc:message-converters>
</mvc:annotation-driven>

and in the Custom Object Mapper, register the appropriate serializers/deserializers IF you want to customize the Json representation.

Similarly with XML, you would typically not write your own converter(Jaxb2RootElementHttpMessageConverter), but use XmlJavaAdapters to customize how some of the elements are serialized.

If you have some new serialization format (not xml, json), then yes, you can attempt writing a HttpMessageConverter from scratch.