我有一个实体 java.time.Instant
用于创建数据字段:
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
public class Item {
private String id;
private String url;
private Instant createdDate;
}
我正在使用 com.fasterxml.jackson.databind.ObjectMapper
将项目作为 JSON 保存到 Elasticsearch:
bulkRequestBody.append(objectMapper.writeValueAsString(item));
ObjectMapper
将这个字段序列化为一个对象:
"createdDate": {
"epochSecond": 1502643595,
"nano": 466000000
}
我正在尝试注释 @JsonFormat(shape = JsonFormat.Shape.STRING)
但它对我不起作用。
我的问题是如何将此字段序列化为 2010-05-30 22:15:52
字符串?
原文由 Uladzislau Kaminski 发布,翻译遵循 CC BY-SA 4.0 许可协议
一种解决方案是使用 jackson-modules-java8 。然后你可以添加一个
JavaTimeModule
到你的对象映射器:默认情况下
Instant
被序列化为纪元值(单个数字中的秒和纳秒):您可以通过在对象映射器中设置来更改它:
这将产生输出:
上面两种格式都是反序列化的,没有任何额外的配置。
要更改序列化格式,只需在字段中添加
JsonFormat
注释:您需要设置时区,否则
Instant
无法正确序列化(它会抛出异常)。输出将是:如果您不想(或不能)使用 java8 模块,另一种选择是使用
java.time.format.DateTimeFormatter
创建自定义序列化器和反序列化器:然后用这些自定义类注释该字段:
输出将是:
一个细节是,在序列化字符串中,您将丢弃秒的小数部分(小数点后的所有内容)。因此,在反序列化时,此信息无法恢复(它将被设置为零)。
在上面的示例中,原始的
Instant
是2017-08-14T12:17:47.720Z
,但序列化后的字符串是2017-08-14 12:17:47
Instant
所以当没有反序列化的秒数时---
是2017-08-14T12:17:47Z
(.720
毫秒丢失)。