如何用 Jackson 序列化 LocalDateTime?

How to serialize LocalDateTime with Jackson?

我得到了如下一段代码:

    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(new JavaTimeModule());
    mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    String now = new ObjectMapper().writeValueAsString(new SomeClass(LocalDateTime.now()));
    System.out.println(now);

我明白了:

{"time":{"hour":20,"minute":49,"second":42,"nano":99000000,"dayOfYear":19,"dayOfWeek":"THURSDAY","month":"JANUARY","dayOfMonth":19,"year":2017,"monthValue":1,"chronology":{"id":"ISO","calendarType":"iso8601"}}}

我要实现的是ISO8601中的字符串

2017-01-19T18:36:51Z

这可能是因为您的代码有误。您正在使用新的未配置的映射器实例,这里是修复:

 ObjectMapper mapper = new ObjectMapper();
 mapper.registerModule(new JavaTimeModule());
 mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
 String now = mapper.writeValueAsString(new SomeClass(LocalDateTime.now()));
 System.out.println(now);

这是您可以为 OffsetDateTime 做的事情:

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "uuuu-MM-dd'T'HH:mm:ss.SSSXXXX")
private OffsetDateTime timeOfBirth;

对于 LocalDateTime,您不能使用 XXXX(区域偏移),因为没有偏移信息。所以你可以放下它。但是 ISO8601 discourages using Local Time 因为它是模棱两可的:

If no UTC relation information is given with a time representation, the time is assumed to be in local time. While it may be safe to assume local time when communicating in the same time zone, it is ambiguous when used in communicating across different time zones. Even within a single geographic time zone, some local times will be ambiguous if the region observes daylight saving time. It is usually preferable to indicate a time zone (zone designator) using the standard's notation.

我使用 SimpleModule,对我来说最好的做法是拥有自己注册的序列化和反序列化实现:

final SimpleModule localDateTimeSerialization = new SimpleModule();
    localDateTimeSerialization.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer());
    localDateTimeSerialization.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer());

objectMapper.registerModule(localDateTimeSerialization);

序列化器:

public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {

  private final DateTimeFormatter format = DateTimeFormatter.ISO_DATE_TIME;

  @Override
  public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
    gen.writeString(value.format(format));
  }
  
}

和反序列化:

public class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {

  private final DateTimeFormatter fmt = DateTimeFormatter.ISO_DATE_TIME;

  @Override
  public LocalDateTime deserialize(JsonParser p, DeserializationContext context) throws IOException {
    return LocalDateTime.parse(p.getValueAsString(), fmt);
  }
  
}