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

2022-09-01 00:22:33

我有一个简单的应用程序与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;
  }
}

在我的只是有: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;
}

我本来以为根据ISO格式格式化,但是我得到了该类的整个JSON转储,如下所示:ZonedDateTime

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

我只有一个应用程序,使用和排除.spring-boot-starter-webspring-boot-starter-jettyspring-boot-starter-tomcat

为什么杰克逊在《春靴》中表现得如此?

** 更新 **

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


答案 1

有一个库 jackson-datatype-jsr310。试试吧。

此库涵盖了新的日期时间 API,并且还包含序列化程序。ZonedDateTime

您所需要的只是添加:JavaTimeModule

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

更新

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

spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS = false

答案 2

如果您不依赖SpringBoot的自动配置功能(您没有在配置文件中提供属性),或者出于任何原因手动创建实例。您可以按编程方式禁用此功能,如下所示:spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS = falseObjectMapper

ObjectMapper m = new ObjectMapper();
m.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);

这是给杰克逊的2.8.7