Spring MVC: Handling Joda Data Types as JSON

PROBLEM

Let’s assume we have the following bean that contains Joda’s LocalDate and LocalDateTime objects:-

public class MyBean {
    private LocalDate date;
    private LocalDateTime dateTime;

    public LocalDate getDate() {
        return date;
    }

    public void setDate(LocalDate date) {
        this.date = date;
    }

    public LocalDateTime getDateTime() {
        return dateTime;
    }

    public void setDateTime(LocalDateTime dateTime) {
        this.dateTime = dateTime;
    }
}

This simple Spring MVC rest controller creates this bean and returns the JSON data back to the client:-

@RequestMapping(value = "/joda", method = RequestMethod.GET)
public ResponseEntity joda() {
    MyBean myBean = new MyBean();
    myBean.setDate(LocalDate.now());
    myBean.setDateTime(LocalDateTime.now());

    return new ResponseEntity<mybean>(myBean, HttpStatus.OK);
}

By default, the generated JSON looks like this:-

{
   "date":
   [
       2015,
       3,
       28
   ],
   "dateTime":
   [
       2015,
       3,
       28,
       18,
       12,
       58,
       992
   ]
}

How do we nicely format these values and still retain the correct data types (LocalDate and LocalDateTime) in MyBean instead of writing our custom formatter and store the values as String?

SOLUTION

First, add a dependency for jackson-datatype-joda.

<dependency>
    <groupid>com.fasterxml.jackson.core</groupid>
    <artifactid>jackson-core</artifactid>
    <version>2.5.1</version>
</dependency>
<dependency>
    <groupid>com.fasterxml.jackson.core</groupid>
    <artifactid>jackson-databind</artifactid>
    <version>2.5.1</version>
</dependency>
<dependency>
    <groupid>com.fasterxml.jackson.core</groupid>
    <artifactid>jackson-annotations</artifactid>
    <version>2.5.1</version>
</dependency>
<dependency>
    <groupid>com.fasterxml.jackson.datatype</groupid>
    <artifactid>jackson-datatype-joda</artifactid>
    <version>2.5.1</version>
</dependency>

Next, instruct MappingJackson2HttpMessageConverter to accept a custom ObjectMapper.

<bean id="objectMapper" class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean" p:indentoutput="true" p:simpledateformat="yyyy-MM-dd'T'HH:mm:ss.SSSZ">
</bean>

<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean" p:targetobject-ref="objectMapper" p:targetmethod="registerModule">
    <property name="arguments">
        <list>
            <bean class="com.fasterxml.jackson.datatype.joda.JodaModule">
        </bean></list>
    </property>
</bean>

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

The generated JSON output now looks like this:-

{
   "date": "2015-03-28",
   "dateTime": "2015-03-28T18:11:16.348"
}

Leave a Reply

Your email address will not be published.