将LocalDate和LocalDateTime序列化为Unix时间戳 [英] Serialize LocalDate and LocalDateTime as Unix timestamps

查看:3151
本文介绍了将LocalDate和LocalDateTime序列化为Unix时间戳的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 java.sql.Timestamp java.util.GregorianCalendar 来使用 java.time。* Spring MVC应用程序中的新类。

I'm moving from using java.sql.Timestamp and java.util.GregorianCalendar to employ java.time.* new classes in a Spring MVC application.

所以我改变了每个

private GregorianCalendar field;

private LocalDate field;

private LocalDateTime field;

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

But now when serializing those beans, they get serialized like this:

"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 并获得:

I found answers to other questions that mention to add a dependency to jackson-datatype-jsr310 and obtained:

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

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

but I still want a unix timestamp when serializing like I got with GregorianCalendar fields: how can I achieve that? Can I avoid a custom serializer (and deserializer)?

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

These are relevant for resource responses and request bodies (as in POST, PUT, etc), not for request parameters.

Jackson ObjectMapper 的配置如下:

The Jackson ObjectMapper is configured like so:

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


推荐答案

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

In the JavaDoc to JavaTimeModule (included in jackson-datatype-jsr310 library), we can read the following:


Most java.time 如果启用了 SerializationFeature.WRITE_DATES_AS_TIMESTAMPS 功能,则将类型序列化为数字(适当的整数或小数)[。 ..]

Most java.time types are serialized as numbers (integers or decimals as appropriate) if the SerializationFeature.WRITE_DATES_AS_TIMESTAMPS feature is enabled [...]

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

[...] If SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS is disabled, timestamps are written as a whole number of milliseconds. [...]

然后:


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

Some exceptions to this standard serialization/deserialization rule:


  • [...]

  • LocalDate LocalTime LocalDateTime OffsetTime ,当 WRITE_DATES_AS_TIMESTAMPS 启用时,它无法转换为时间戳,而是表示为数组。

  • [...]
  • LocalDate, LocalTime, LocalDateTime, and OffsetTime, which cannot portably be converted to timestamps and are instead represented as arrays when WRITE_DATES_AS_TIMESTAMPS is enabled.

您确实可以看到 LocalDateTime 无法无处不在地转换为Unix时间戳,因为它的 toEpochSecond 方法将 ZoneOffset 作为参数。

You can indeed see that LocalDateTime cannot be ubiquitously converted to the Unix timestamp because its toEpochSecond method takes ZoneOffset as parameter.

总结,你可以做的最好的事情就是用 Instant LocalDateTime code>(参见这个很棒的答案解释 LocalDateTime Instant 之间的区别。

To sum up, it seems the best thing you can do is replacing LocalDateTime with Instant (see this great answer for an explanation of the difference between LocalDateTime and Instant).

除此之外,你确实需要自定义 JsonSerializer JsonDeserializer

Other than that, you would indeed need custom JsonSerializer and JsonDeserializer.

这是一个有效的代码示例:

Here's a working code sample:

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

这篇关于将LocalDate和LocalDateTime序列化为Unix时间戳的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆