Java Spring Jackons Date serialization

15,508

Solution 1

Much simpler way to do this now in Spring 3.1.

public class CustomObjectMapper extends ObjectMapper {

    public CustomObjectMapper() {
        configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false);            
        setDateFormat(new ISO8601DateFormat());
    }
}

And then register this as a bean and customize the mvc:annotation-driven element.

<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
                <property name="objectMapper" ref="customObjectMapper"/>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

<bean id="customObjectMapper" class="CustomObjectMapper"/>

Solution 2

Solution using Spring 3.1.3 and Jackson 2.1.0 that works for me (based on Ryans answer and Kornys notes with additional change in Java code "SerializationConfig.Feature" -> "SerializationFeature")

public class DateObjectMapper extends ObjectMapper {

public DateObjectMapper() {
    configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);            
}

Configuration:

<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="objectMapper" ref="dateObjectMapper"/>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

<bean id="dateObjectMapper" class="DateObjectMapper"/>

Solution 3

I found the following to work with Spring Platform 2.0 (Spring 4.2) and Jackson 2.6.3

pom.xml

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
</dependency>

<dependency>
  <groupId>com.fasterxml.jackson.datatype</groupId>
  <artifactId>jackson-datatype-joda</artifactId>
</dependency>

applicationContext.xml

<mvc:annotation-driven>
  <mvc:message-converters>
     <beans:bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
       <beans:property name="objectMapper">
         <beans:bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
         <beans:property name="featuresToDisable">
           <beans:array>
             <util:constant static-field="com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS"/>
           </beans:array>
         </beans:property>               
         </beans:bean>
       </beans:property>
     </beans:bean>
   </mvc:message-converters>        
</mvc:annotation-driven>

Solution 4

I've fixed my problem. So for reference to others with a similar problem.

I've deleted the following elements in the spring context config xml:

<mvc:annotation-driven/>

and

<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="jacksonSerializationConfig" />
<property name="targetMethod" value="setDateFormat" />
<property name="arguments">
    <list>
        <value type="java.text.SimpleDateFormat">yyyy-MM-dd'T'HH:mm:ss.SSSZ</value>
    </list>
</property>

Then I added the following:

<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
    <property name="order" value="1" />
</bean>

and changed the following:

<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="jacksonSerializationConfig" />
<property name="targetMethod" value="enable" />
<property name="arguments">
    <list>
        <value type="org.codehaus.jackson.map.SerializationConfig.Feature">WRITE_DATES_AS_TIMESTAMPS</value>
    </list>
</property>

in

<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="jacksonSerializationConfig" />
<property name="targetMethod" value="disable" />
<property name="arguments">
    <list>
        <value type="org.codehaus.jackson.map.SerializationConfig.Feature">WRITE_DATES_AS_TIMESTAMPS</value>
    </list>
</property>

After this Spring was able to serialize my date into json as a ISO date.

Share:
15,508

Related videos on Youtube

MystyxMac
Author by

MystyxMac

I'm a Software Engineer and worked on various platforms, like Java, C#, iOS and Android. SOreadytohelp

Updated on June 04, 2022

Comments

  • MystyxMac
    MystyxMac almost 2 years

    I'm using Spring MVC and Jackson for JSON de/serialization. But im facing a problem with serializing a date.

    By default Jackson serialize a date as an epoch. But i want to serialize it as a ISO date (i.e. 06-10-2011 11:00:00).

    The code below is my spring config, but it does not work. It's still returning an epoch date.

    So my question is, how can I serialize to a non-epoch date?

    <!-- JSON -->
    <bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
        <property name="supportedMediaTypes" value="application/json" />
        <property name="objectMapper" ref="jacksonObjectMapper" />
    </bean>
    
    <bean id="jacksonObjectMapper" class="org.codehaus.jackson.map.ObjectMapper" />
    
    <bean id="jacksonSerializationConfig" class="org.codehaus.jackson.map.SerializationConfig" factory-bean="jacksonObjectMapper" factory-method="getSerializationConfig" />
    
    <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <property name="targetObject" ref="jacksonSerializationConfig" />
        <property name="targetMethod" value="setSerializationInclusion" />
        <property name="arguments">
            <list>
                <value type="org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion">NON_NULL</value>
            </list>
        </property>
    </bean>
    
    <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <property name="targetObject" ref="jacksonSerializationConfig" />
        <property name="targetMethod" value="setDateFormat" />
        <property name="arguments">
            <list>
                <value type="java.text.SimpleDateFormat">yyyy-MM-dd'T'HH:mm:ss.SSSZ</value>
            </list>
        </property>
    </bean>
    
    <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <property name="targetObject" ref="jacksonSerializationConfig" />
        <property name="targetMethod" value="enable" />
        <property name="arguments">
            <list>
                <value type="org.codehaus.jackson.map.SerializationConfig.Feature">WRITE_DATES_AS_TIMESTAMPS</value>
            </list>
        </property>
    </bean>
    
  • Korny
    Korny about 11 years
    Note that if using Spring 3.2 and Jackson2, this should be org.springframework.http.converter.json.MappingJackson2HttpM‌​essageConverter Also note that if you have two "<mvc:annotation-driven>" sections, this may silently fail with no warnings :)
  • Korny
    Korny about 11 years
    Oh and you don't need the "setDateFormat" line at all - if you turn off WRITE_DATES_AS_TIMESTAMPS you get ISO 6801 dates by default.
  • Ryan Walls
    Ryan Walls about 11 years
    @Korny. Thanks. Didn't know it fell back to 8601 automatically.
  • Glenn Lawrence
    Glenn Lawrence almost 10 years
    I upgraded from Spring 3.0 to do this but hit a runtime problem with reading the XML. I found I had to change 3.0.xsd to 3.1.xsd in the xsi:schemaLocation of the XML file or I would get "'mvc:annotation-driven' must have no character or element information item [children]"
  • Jason Harrison
    Jason Harrison over 7 years
    this must be for a much older version of jackson, as the classes have been moved from org.codehaus.jackson to com.fasterxml.jackson since version 2.0
  • MystyxMac
    MystyxMac over 7 years
    @JasonHarrison That is correct as this question was asked back in 2011.
  • vbezhenar
    vbezhenar about 5 years
    Thanks a lot, this is awesome.