I'm using the library described the Jackson Datatype JSR310 page but I'm still having difficulty getting it to work.
I have configured the following bean:
@Bean
@Primary
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JSR310Module());
return mapper;
}
When I call my REST API the date format output is yyyy-MM-dd'T'HH:ss.SSSSSS
, e.g. 2015-04-11T00:10:38.905847
. This gets handled by my AngularJS code just fine.
When I want to submit something to the REST API the date is posted as yyyy-MM-dd'T'HH:mm:ss.SSS'Z'
, e.g. 2015-04-09T08:30:00.000Z
Jackson keeps complaining about the 'Z' at the end. If I look at the LocalDateTimeDeserializer
in the documentation it uses the DateTimeFormatter.ISO_LOCAL_DATE_TIME
which boils to ISO_LOCAL_DATE'T'ISO_LOCAL_TIME
and it mentions it has no override zone.
So I figured I should set the DateFormat
on the ObjectMapper
I'm creating:
@Bean
@Primary
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JSR310Module());
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"));
return mapper;
}
But this does nothing. I changed it to something simple like yyyy-MM-dd
but the serialized date remained in the previous format and the deserialization isn't affected either.
What am I doing wrong here to get this to work? The date format in my JavaScript code is, as far as I know the ISO 8601 format...
It's not necessary to write your own serializer. It's enough use the default one, but making an instance with another format (the time_zone
one) so that the exceeding part is just cut:
new LocalDateTimeDeserializer(DateTimeFormatter.ISO_DATE_TIME)
In my case I've got a contextResolver
like this to achieve at configuration level:
@Service
@Provider
public class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> {
private final ObjectMapper mapper;
public ObjectMapperContextResolver() {
mapper = new ObjectMapper();
JavaTimeModule javaTimeModule=new JavaTimeModule();
// Hack time module to allow 'Z' at the end of string (i.e. javascript json's)
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ISO_DATE_TIME));
mapper.registerModule(javaTimeModule);
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
}
@Override
public ObjectMapper getContext(Class<?> type) {
return mapper;
}
}
For now LocalDateTimeDeserializer
does not seem to respect the date format set for the object mapper.
To make it work you can override LocalDateTimeDeserializer
or switch to use ZoneDateTime
which handles the 'Z' char at the end.
Here is an example:
public class Java8DateFormat {
public static void main(String[] args) throws IOException {
final ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JSR310Module());
// mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"));
final String date = mapper.writeValueAsString(new Date());
System.out.println(date);
System.out.println(mapper.readValue(date, ZonedDateTime.class));
}
}
Output:
"2015-04-11T18:24:47.815Z"
2015-04-11T18:24:47.815Z[GMT]
Hibernate 4, Spring 4 - REST WS, Client - Spring Boot 1.5.2. In my case I used in Entity ZonedDateTime class to map Timestamp in database. Hibernate as well as Spring Boot REST works fine. I must only add libraries into pom file:
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.datatype/jackson-datatype-jsr310 -->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
</dependency>
So I suppose, that converter is implemented inside Spring for LocalDateTime as well.The jackson.version is the latest one.