Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jackson serializes a ZonedDateTime wrongly in Spring Boot

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/

like image 584
jbx Avatar asked Aug 22 '16 18:08

jbx


People also ask

Is Jackson Databind included in spring boot?

If you use Spring Boot, the jackson-databind dependency comes in the spring-boot-starter-json module (which also is included in other spring boot started moduled, like spring-boot-starter-web ).

What does Jackson do in spring boot?

Data binding is a JSON processing model that allows for seamless conversion between JSON data and Java objects. With data binding, you create POJOs following JavaBeans convention with properties corresponding to the JSON data. The Jackson ObjectMapper is responsible for mapping the JSON data to the POJOs.

Does spring boot have Jackson ObjectMapper?

Overview. When using JSON format, Spring Boot will use an ObjectMapper instance to serialize responses and deserialize requests. In this tutorial, we'll take a look at the most common ways to configure the serialization and deserialization options. To learn more about Jackson, be sure to check out our Jackson tutorial.

Does spring use Jackson by default?

Spring Framework and Spring Boot provide builtin support for Jackson based XML serialization/deserialization. As soon as you include the jackson-dataformat-xml dependency to your project, it is automatically used instead of JAXB2.


1 Answers

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:

ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new JavaTimeModule()); 

UPDATE

To convert datetime to ISO-8601 string you should disable WRITE_DATES_AS_TIMESTAMPS feature. You can easily do by either overriding ObjectMapper bean or by using application properties:

spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS = false 
like image 63
vsminkov Avatar answered Sep 23 '22 01:09

vsminkov