【问题标题】:Deserialize millisecond timestamp to java.time.Instant将毫秒时间戳反序列化为 java.time.Instant
【发布时间】:2018-01-27 12:09:39
【问题描述】:

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

这是我在尝试读取时间戳时看到的:

1503115200000

Jackson 将 Instant 字段设置为 +49601-10-28T16:00:00Z

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

有没有办法将 Jackson 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 或纪元秒,例如 1503115200Instant 字段能够正确设置。

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

【问题讨论】:

    标签: java serialization jackson deserialization java-time


    【解决方案1】:

    如果您不想编辑或创建对象映射器,更灵活的解决方案可能是编写自己的转换器类。

    public class LongToInstantConverter extends StdConverter<Long, Instant> {
        public Instant convert(final Long value) {
            return Instant.ofEpochMilli(value);
        }
    }
    

    你只需要在你的类中添加注解

    @JsonDeserialize(converter = LongToInstantConverter.class)
    private Instant sentDate;
    

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

        【解决方案3】:

        来自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。

        【讨论】:

          【解决方案4】:

          解决方案是将.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);
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-03-04
            • 2016-03-04
            • 2013-03-09
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多