Mar*_*unt 7 java serialization jackson deserialization java-time
我正在尝试使用Jackson读取JSON文件,并以Java的纪元毫秒形式存储其中一个字段Instant,但是反序列化的行为不符合预期。
这是我尝试读取时间戳时看到的内容:
1503115200000
杰克逊将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);
Run Code Online (Sandbox Code Playgroud)
注意
如果我将输入JSON更改为ISO日期(例如)2017-08-19T04:00:00Z或epoch seconds(例如纪元秒),1503115200则Instant字段可以正确设置。
不幸的是JSON输入必须是纪元毫秒,例如1503115200000。
小智 14
对于那些使用Spring Boot并在 rest 请求反序列化期间遇到此问题的人 - 在 application.properties 中提供:
spring.jackson.deserialization.read-date-timestamps-as-nanoseconds=false
@JB Nizet 答案是正确的,但由于 Spring Boot 内部有自己的 ObjectMapper - 您需要在属性中配置此值。
如果您不想编辑或创建对象映射器,更灵活的解决方案可能是编写自己的转换器类。
public class LongToInstantConverter extends StdConverter<Long, Instant> {
public Instant convert(final Long value) {
return Instant.ofEpochMilli(value);
}
}
Run Code Online (Sandbox Code Playgroud)
您只需要在您的类中添加注释即可
@JsonDeserialize(converter = LongToInstantConverter.class)
private Instant sentDate;
Run Code Online (Sandbox Code Playgroud)
解决方案是将其添加.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);
Run Code Online (Sandbox Code Playgroud)
如果启用了{@code READ_DATE_TIMESTAMPS_AS_NANOSECONDS}(默认情况下),则更模糊的整数类型将读取为不带小数点的小数秒,否则它们将读取为毫秒。
因此,您需要禁用 READ_DATE_TIMESTAMPS_AS_NANOSECONDS。
| 归档时间: |
|
| 查看次数: |
3983 次 |
| 最近记录: |