如何用杰克逊序列化 LocalDateTime?

Posted

技术标签:

【中文标题】如何用杰克逊序列化 LocalDateTime?【英文标题】:How to serialize LocalDateTime with Jackson? 【发布时间】:2017-06-04 14:37:37 【问题描述】:

我得到以下代码:

    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

【问题讨论】:

会不会有这样的工作:DateFormat df = new SimpleDateFormat("MM/dd/yy hh:mm a");然后:mapper.setDateFormat(df); 【参考方案1】:

这可能是由于您的代码中的错误。您正在使用新的未配置的映射器实例,这是修复:

 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);

【讨论】:

【参考方案2】:

这就是你可以为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 是模棱两可的:

如果没有给出带有时间表示的 UTC 关系信息, 时间假定为当地时间。虽然它可能是安全的 在同一时区进行通信时假设本地时间,它是 用于跨时区通信时模棱两可。甚至 在一个地理时区内,一些当地时间将是 如果该地区遵守夏令时,则不明确。通常是 最好用 标准符号。

【讨论】:

【参考方案3】:

我使用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);
  
  

【讨论】:

以上是关于如何用杰克逊序列化 LocalDateTime?的主要内容,如果未能解决你的问题,请参考以下文章

使用杰克逊的 LocalDateTime 解析

fix bug:解决在Spring项目实践中LocalDateTime无法序列化反序列化的问题

龙目岛没有创建默认构造函数导致杰克逊数据绑定失败[重复]

春季靴子泽西杰克逊

使用Jackson“意外令牌(START_OBJECT)使用LocalDateTime将JSON解析为POJO,预期VALUE_STRING:预期的数组或字符串。”

LocalDateTime - 使用 LocalDateTime.parse 反序列化