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"/> </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"/> </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" }