I'm writing a Java 8 Spring MVC application that communicates with a legacy Progress OpenEdge application using a REST service (I'm using Spring's RestTemplate for this). The data I need to read from and write to the Progress application contains some dates. In the Java application, I use a java.time.LocalDate datatype to represent these fields and I'm using Jackson to serialize / deserialize the data into / from Json.
The problem I'm having is the following. When I send data from the Progress Application, the date is send as '2015-01-02' and stored in my Java entity as a LocalDate as expected. When the data is send to the web front-end the Json also contains the date in the same format. When I change information in the web front-end and apply it, it's also send back to the Java application as '2015-01-02' and again stored as a LocalDate without problems. But when I than send the data onwards to the Progress application, the Json I receive doesn't contain the date as '2015-01-02' but as an array containing three fields (2015.0, 1.0, 2.0) and the Progress application is unable to assign this back to a date field in the database.
Offcourse I could write a conversion on the Progress side to convert the array back into a date, but I'd like to avoid this as I would expect the date to always be send in the ISO 8601 format.
According to the information I find on Jackson, a java.time.LocalDate is represented as an array when WRITE_DATES_AS_TIMESTAMPS is enabled, but I have this disabled (And when the date is send to the web front-end, it's not being send as an array...)
Here is some relevant code:
The CustomObjectMapper:
@Service
public class CustomObjectMapper extends ObjectMapper
{
public CustomObjectMapper()
{
this.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,
false);
}
}
The configuration in my servlet.xml
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper" ref="customObjectMapper"/>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<bean id="customObjectMapper" class="com.msoft.utility.CustomObjectMapper"/>
The field definition:
@JsonDeserialize(using = LocalDateDeserializer.class)
@JsonSerialize(using = LocalDateSerializer.class)
private LocalDate deliveryDate;
I'm using Java 8 with Spring 4.1.5 and Jackson 2.5.1.
Any tips how I could get this working or were to search for a solution would be greatly appreciated as I've already been working on this for almost 2 days...
Thanks
EDIT:
Some extra info...
I've included the Jackson JSR-310 module in my pom.xml. Here is the releveant part of my pom file...
<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-annotations</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.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.5.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.1.5.RELEASE</version>
<scope>test</scope>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.7.2.RELEASE</version>
</dependency>
Also, if I understood correctly, Spring will register this module automatically when it's detected. See the info on Jackson2ObjectMapperFactoryBean
Note that Jackson's JSR-310 and Joda-Time support modules will be registered automatically when available (and when Java 8 and Joda-Time themselves are available, respectively).
So I don't think I should have to do anything else to get this working correctly, but obviously I'm still missing something...
This worked for me, and I'm not using Spring boot.
@Configuration
@EnableWebMvc
public class SpringMvcConfiguration extends WebMvcConfigurerAdapter {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
}
}
I think you just need to register JSR-310 (Java 8 Date/Time) module:
https://github.com/FasterXML/jackson-datatype-jsr310/
since Jackson core can not rely on any Java 8 features (baseline at this point, with 2.5, is Java 6). And going forward support for most datatype libraries will go through plug-in modules anyway.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With