I have a simple application with Spring Boot and Jetty. I have a simple controller returning an object which has a Java 8 ZonedDateTime
:
public class Device {
// ...
private ZonedDateTime lastUpdated;
public Device(String id, ZonedDateTime lastUpdated, int course, double latitude, double longitude) {
// ...
this.lastUpdated = lastUpdated;
// ...
}
public ZonedDateTime getLastUpdated() {
return lastUpdated;
}
}
In my RestController
I simply have:
@RequestMapping("/devices/")
public @ResponseBody List<Device> index() {
List<Device> devices = new ArrayList<>();
devices.add(new Device("321421521", ZonedDateTime.now(), 0, 39.89011333, 24.438176666));
return devices;
}
I was expecting the ZonedDateTime
to be formatted according to the ISO format, but instead I am getting a whole JSON dump of the class like this:
"lastUpdated":{"offset":{"totalSeconds":7200,"id":"+02:00","rules":{"fixedOffset":true,"transitionRules":[],"transitions":[]}},"zone":{"id":"Europe/Berlin","rules":{"fixedOffset":false,"transitionRules":[{"month":"MARCH","timeDefinition":"UTC","standardOffset":{"totalSeconds":3600,"id":"+01:00","rules":{"fixedOffset":true,"transitionRules":[],"transitions":[]}},"offsetBefore":{"totalSeconds":3600,"id":"+01:00","rules":{"fixedOffset":true,"transitionRules":[],"transitions":[]}},"offsetAfter":{"totalSeconds":7200,"id":"+02:00", ...
I just have a spring-boot-starter-web
application, using spring-boot-starter-jetty
and excluding spring-boot-starter-tomcat
.
Why is Jackson behaving like this in Spring Boot?
** UPDATE **
For those looking for a full step by step guide how to solve this I found this after asking the question: http://lewandowski.io/2016/02/formatting-java-time-with-spring-boot-using-json/
There is a library jackson-datatype-jsr310. Try it.
This library covers new datetime API and includes serializers for
ZonedDateTime
too.All you need is just to add
JavaTimeModule
:UPDATE
To convert datetime to
ISO-8601
string you should disableWRITE_DATES_AS_TIMESTAMPS
feature. You can easily do by either overridingObjectMapper
bean or by using application properties:The answer was already mentioned above but I think it's missing some info. For those looking to parse Java 8 timestamps in many forms (not just ZonedDateTime). You need a recent version of
jackson-datatype-jsr310
in your POM and have the following module registered:To test this code
Note that you can configure your object mapper globally in Spring or dropwizard to achieve this. I have not yet found a clean way to do this as an annotation on a field without registering a custom (de)serializer.
If you either don't rely on SpringBoot's auto-configuration feature - you don't provide
spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS = false
property into your configuration file - or for whatever reason you createObjectMapper
instance manually. You can disable this feature programatically as follows:this is for jackson
2.8.7