一种解决方案是使用jackson-modules-java8。然后,您可以
JavaTimeModule向您的对象映射器添加一个:
ObjectMapper objectMapper = new ObjectMapper();JavaTimeModule module = new JavaTimeModule();objectMapper.registerModule(module);
默认情况下,
Instant序列化为纪元值(单个数字中的秒和纳秒):
{"createdDate":1502713067.720000000}您可以通过在对象映射器中进行设置来更改此设置:
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
这将产生输出:
{"createdDate":"2017-08-14T12:17:47.720Z"}以上两种格式均已反序列化,而无需任何其他配置。
要更改序列化格式,只需
JsonFormat在字段中添加注释:
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "UTC")private Instant createdDate;
您需要设置时区,否则
Instant无法正确序列化(抛出异常)。输出将是:
{"createdDate":"2017-08-14 12:17:47"}如果您不想(或不能)使用java8模块,另一种选择是使用以下命令创建自定义序列化器和反序列化器
java.time.format.DateTimeFormatter:
public class MyCustomSerializer extends JsonSerializer<Instant> { private DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneOffset.UTC); @Override public void serialize(Instant value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException { String str = fmt.format(value); gen.writeString(str); }}public class MyCustomDeserializer extends JsonDeserializer<Instant> { private DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneOffset.UTC); @Override public Instant deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { return Instant.from(fmt.parse(p.getText())); }}然后,使用这些自定义类对字段进行注释:
@JsonDeserialize(using = MyCustomDeserializer.class)@JsonSerialize(using = MyCustomSerializer.class)private Instant createdDate;
输出将是:
{"createdDate":"2017-08-14 12:17:47"}一个细节是,在序列化的字符串中,您将丢弃秒的小数部分(小数点后的所有内容)。因此,在反序列化时,此信息无法恢复(将其设置为零)。
在上面的示例中,原始
Instant值为
2017-08-14T12:17:47.720Z,但是序列化的字符串为
2017-08-1412:17:47(不包括秒),因此反序列化时的结果
Instant为
2017-08-14T12:17:47Z(
.720丢失了毫秒)。



