Jackson在Spring Boot中错误地序列化了ZonedDateTime

时间:2021-08-13 18:02:50

I have a simple application with Spring Boot and Jetty. I have a simple controller returning an object which has a Java 8 ZonedDateTime:

我有一个Spring Boot和Jetty的简单应用程序。我有一个简单的控制器返回一个具有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:

在我的RestController中,我只需:

@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:

我期待ZonedDateTime根据ISO格式进行格式化,但是我得到了类的整个JSON转储,如下所示:

"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.

我只有一个spring-boot-starter-web应用程序,使用spring-boot-starter-jetty并且不包括spring-boot-starter-tomcat。

Why is Jackson behaving like this in Spring Boot?

杰克逊为什么在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/

对于那些寻求完整的一步一步指导如何解决这个问题的人,我在问了这个问题后发现了这个问题:http://lewandowski.io/2016/02/formatting-java-time-with-spring-boot-using-json/

1 个解决方案

#1


25  

There is a library jackson-datatype-jsr310. Try it.

有一个库jackson-datatype-jsr310。尝试一下。

This library covers new datetime API and includes serializers for ZonedDateTime too.

该库涵盖了新的datetime API,并且还包含ZonedDateTime的序列化程序。

All you need is just to add JavaTimeModule:

您只需要添加JavaTimeModule:

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

UPDATE

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:

要将datetime转换为ISO-8601字符串,您应该禁用WRITE_DATES_AS_TIMESTAMPS功能。您可以通过重写ObjectMapper bean或使用应用程序属性轻松完成:

spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS = false

#1


25  

There is a library jackson-datatype-jsr310. Try it.

有一个库jackson-datatype-jsr310。尝试一下。

This library covers new datetime API and includes serializers for ZonedDateTime too.

该库涵盖了新的datetime API,并且还包含ZonedDateTime的序列化程序。

All you need is just to add JavaTimeModule:

您只需要添加JavaTimeModule:

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

UPDATE

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:

要将datetime转换为ISO-8601字符串,您应该禁用WRITE_DATES_AS_TIMESTAMPS功能。您可以通过重写ObjectMapper bean或使用应用程序属性轻松完成:

spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS = false