将毫秒时间戳反序列化为java.time.Instant

时间:2017-08-18 18:22:46

标签: java serialization jackson deserialization java-time

我尝试使用Jackson读取JSON文件并将其中一个字段存储为epoch毫秒作为Java Instant,但是反序列化的行为不符合预期。

以下是我在尝试阅读时间戳时所看到的内容:

  

1503115200000

杰克逊正在将Instant字段设为+49601-10-28T16:00:00Z

这似乎是因为杰克逊的默认设置是使用Instant.ofEpochSecond(Long l)而不是Instant.ofEpochMilli(Long l)来读取时间戳。

有没有办法让杰克逊ObjectMapper使用ofEpochMilli方法代替?这就是我目前对ObjectMapper

的看法
ObjectMapper om = new ObjectMapper()
            .registerModule(new JavaTimeModule())
            .configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, false)
            .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
            .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
            .setSerializationInclusion(Include.NON_NULL);

注意

如果我将输入JSON更改为ISO日期(例如2017-08-19T04:00:00Z)或时间秒(例如1503115200),则Instant字段可以正确设置。

不幸的是,JSON输入必须是纪元毫秒,例如1503115200000

3 个答案:

答案 0 :(得分:1)

解决方案是将.configure(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS, false)添加到ObjectMapper。完整的ObjectMapper如下所示:

ObjectMapper om = new ObjectMapper()
            .registerModule(new JavaTimeModule())
            .configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, false)
            .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
            .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
            .configure(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS, false)
            .setSerializationInclusion(Include.NON_NULL);

答案 1 :(得分:1)

来自https://github.com/FasterXML/jackson-modules-java8/blob/master/datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/JavaTimeModule.java

  

如果启用了{@code READ_DATE_TIMESTAMPS_AS_NANOSECONDS}(默认情况下),则更不明确的整数类型将被读取为没有小数点的小数秒,否则它们将被读取为毫秒。

所以你需要禁用READ_DATE_TIMESTAMPS_AS_NANOSECONDS。

答案 2 :(得分:1)

对于那些使用 Spring Boot 并在其余请求反序列化期间遇到此问题的用户-在application.properties中提供此信息:

spring.jackson.deserialization.read-date-timestamps-as-nanoseconds=false

@JB Nizet的答案是正确的,但是由于Spring Boot内部具有它自己的ObjectMapper-您需要在属性中配置该值。