一种解决方案是使用 jackson-modules-java8。然后,您可以向对象映射器添加 一个:JavaTimeModule
ObjectMapper objectMapper = new ObjectMapper();
JavaTimeModule module = new JavaTimeModule();
objectMapper.registerModule(module);
默认情况下,将 序列化为 epoch 值(单个数字中的秒和纳秒):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-14 12:17:47
Instant
2017-08-14T12:17:47Z
.720