phi phi - 5 months ago 49
JSON Question

Deserialization of java.util.time.LocalDateTime to joda LocalDateTime

I've got REST webservice exposing resources with creation date. It is written in Java 8 - using LocalDateTime. Jackson 2 is serializing it to:

"createdDate": [2016, 5, 19, 18, 6, 59, 639000000]


In other application my goal is to consume this rest, but there is only Java 7, so I decided to use joda-time library in DTO. I've set up RestTemplate like this:

RestTemplate restTemplate = new RestTemplate();
MappingJackson2HttpMessageConverter e = new MappingJackson2HttpMessageConverter();
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JodaModule());
e.setObjectMapper(mapper);
messageConverters.add(e);
restTemplate.setMessageConverters(messageConverters);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<NewUserData> request = new HttpEntity<>(user, headers);


POST is successful, however while deserializing answer (with createdDate field from above) exception is thrown:

org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Value 696000000 for millisOfSecond must be in the range [0,999] (through reference chain: com.foobar.dto.user.UserItem["createdDate"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Value 696000000 for millisOfSecond must be in the range [0,999] (through reference chain: com.foobar.dto.user.UserDisplayItem["createdDate"])


My dependencies looks like this:

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc-portlet</artifactId>
<version>3.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.9.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-joda</artifactId>
<version>2.7.4</version>
</dependency>


Should I write my own Jackson deserializer or maybe i could use other library/version?

phi phi
Answer

I've fixed my problem. Here is my new jackson configuration on server (instead of using default):

private MappingJackson2HttpMessageConverter customMappingJackson2HttpMessageConverter() {
    MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    objectMapper.setDateFormat(new ISO8601DateFormat());
    objectMapper.registerModule(new JavaTimeModule());

    jsonConverter.setObjectMapper(objectMapper);
    return jsonConverter;
}

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    converters.add(customMappingJackson2HttpMessageConverter());
}

Registering module, disabling writing dates as timestamps and registering JavaTimeModule did the job. Thanks to this, server serialized dates to:

"createdDate":"2016-06-07T15:15:25"

In client application i had to change jackson configuration adding:

mapper.setDateFormat(new ISO8601DateFormat());
Comments