java - 将 LocalDate 和 LocalDateTime 序列化为 Unix 时间戳

标签 java spring spring-mvc jackson java-time

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

所以我改变了一切

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

最佳答案

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

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

[...] 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, 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 作为参数。

总而言之,看来您能做的最好的事情就是将 LocalDateTime 替换为 Instant(参见 this great answer 的解释) LocalDateTimeInstant 之间的区别。

除此之外,您确实需要自定义 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;
}

关于java - 将 LocalDate 和 LocalDateTime 序列化为 Unix 时间戳,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51284630/

相关文章:

java - Maven 插件用红色下划线 + 创建类路径中定义的名为 'entityManagerFactory' 的 bean 时出错

java - 如何初始化网络服务

java - 如何在运行时更改以下 bean 属性?

Java - Getter/Setter、行为和接口(interface)

java - 是否有用于使用体素引擎进行渲染的 Java 库?

java - 将 Converter 用于 Boolean 类型时,Spring 复选框 JSP 标记被破坏

java - 如何与 Maven 一起运行 xml 配置驱动和无 xml Spring Web 应用程序?

java - ClassReader 中的 ArrayIndexOutOfBoundsException 导致加载 ApplicationContext 失败

java - 为什么 Java N1QL 中的 ORDER BY 不能按预期工作

java - 如何在 Android WebView 中访问 WhatsAppWeb?