【问题标题】:Serialize LocalDate and LocalDateTime as Unix timestamps将 LocalDate 和 LocalDateTime 序列化为 Unix 时间戳
【发布时间】:2018-12-19 10:40:21
【问题描述】:

我正在从使用 java.sql.Timestampjava.util.GregorianCalendar 转变为在 Spring MVC 应用程序中使用 java.time.* 新类。

所以我改变了每个

private GregorianCalendar field;

private LocalDate field;

private LocalDateTime field;

但是现在在序列化这些 bean 时,它们会像这样被序列化:

"field": {
      "year": 1970,
      "month": "JANUARY",
      "dayOfMonth": 18,
      "dayOfWeek": "SUNDAY",
      "era": "CE",
      "dayOfYear": 18,
      "leapYear": false,
      "monthValue": 1,
      "chronology": {
        "id": "ISO",
        "calendarType": "iso8601"
      }
    },

我找到了提到向jackson-datatype-jsr310 添加依赖项的其他问题的答案并获得:

 "field": [
      1970,
      1,
      18
    ],

但我在序列化时仍然想要一个 unix 时间戳,就像我使用 GregorianCalendar 字段获得的那样:我该如何实现?我可以避免使用自定义序列化器(和反序列化器)吗?

这些与资源响应和请求正文相关(如 POST、PUT 等),而不是请求参数。

Jackson ObjectMapper 配置如下:

jacksonConverter.getObjectMapper().enable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
jacksonConverter.getObjectMapper().disable(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS);

【问题讨论】:

  • 如果my answer 对您有帮助,请告诉我(如果没有,请告诉我原因)。
  • @TomaszLinkowski 当然我会的,只要我回到我需要的项目 :-)

标签: java spring spring-mvc jackson java-time


【解决方案1】:

JavaTimeModule(包含在jackson-datatype-jsr310库中)的JavaDoc中,我们可以阅读以下内容:

如果启用了SerializationFeature.WRITE_DATES_AS_TIMESTAMPS 功能,大多数java.time 类型将被序列化为数字(整数或小数)[...]

[...] 如果SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS 被禁用,时间戳将写入整数毫秒。 [...]

然后:

此标准序列化/反序列化规则的一些例外情况:

  • [...]
  • LocalDateLocalTimeLocalDateTimeOffsetTime,它们不能可移植地转换为时间戳,而是在启用 WRITE_DATES_AS_TIMESTAMPS 时表示为数组。

您确实可以看到LocalDateTime 不能普遍转换为Unix 时间戳,因为它的toEpochSecond 方法以ZoneOffset 作为参数。

总结,您可以做的最好的事情似乎是将LocalDateTime替换为Instant(有关LocalDateTimeInstant之间区别的解释,请参阅this great answer )。

除此之外,您确实需要自定义 JsonSerializerJsonDeserializer


这是一个工作代码示例:

public static void main(String[] args) throws Exception {
    ObjectMapper objectMapper = new ObjectMapper()
            .registerModule(new JavaTimeModule())
            .disable(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS);

    Entity entity = new Entity(Instant.now());

    StringWriter writer = new StringWriter();
    objectMapper.writeValue(writer, entity);
    System.out.println(writer.getBuffer());
}

@lombok.Value
static class Entity {
    Instant timestamp;
}

【讨论】:

    猜你喜欢
    • 2015-12-30
    • 1970-01-01
    • 1970-01-01
    • 2017-05-11
    • 1970-01-01
    • 2017-11-01
    • 2018-04-09
    • 2017-10-15
    • 1970-01-01
    相关资源
    最近更新 更多