将毫秒时间戳反序列化为 java.time.Instant
Posted
技术标签:
【中文标题】将毫秒时间戳反序列化为 java.time.Instant【英文标题】:Deserialize millisecond timestamp to 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
或纪元秒,例如 1503115200
,Instant
字段能够正确设置。
不幸的是,JSON 输入必须是纪元毫秒,例如1503115200000
。
【问题讨论】:
【参考方案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);
【讨论】:
以上是关于将毫秒时间戳反序列化为 java.time.Instant的主要内容,如果未能解决你的问题,请参考以下文章