我在 Spring Boot 应用程序中使用 Java 8 DateTime 和 Jackson jsr 310 支持。
我禁用了SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,以强制 Jackson 将 localDatetime 序列化为字符串而不是 int 数组。
但是当日期时间微秒或九秒以 0 结尾时,我发现了一个奇怪的格式问题。我认为序列化结果可能等于 date.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME),但事实并非如此,format方法省略了零。
完整的示例测试代码。
private LocalDateTime date;
private OffsetDateTime offsetDate;
private ZonedDateTime zonedDate;
@Before
public void setup() throws ServletException {
date = LocalDateTime.of(2015, 8, 15, 11, 40, 10, 100_000_000);
offsetDate = OffsetDateTime.of(2015, 8, 15, 11, 40, 10, 100_000_000, ZoneOffset.ofHours(8));
zonedDate = ZonedDateTime.of(2015, 8, 15, 11, 40, 10, 100_000_000, ZoneId.of("Asia/Shanghai"));
}
@Test
public void testDateFormat() throws Exception {
Map<String, Object> map = new HashMap<>();
map.put("localDate", date);
map.put("offsetDate", offsetDate);
map.put("zonedDate", zonedDate);
String json = objectMapper.writeValueAsString(map);
log.debug("converted json result @" + json);
JsonNode rootNode = objectMapper.readTree(json);
JsonNode localDateNode = rootNode.get("localDate");
assertEquals("local date should be equals", date.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME), localDateNode.textValue());
JsonNode offsetDateNode = rootNode.get("offsetDate");
assertEquals("offsetDate date should be equals", offsetDate.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME), offsetDateNode.textValue());
JsonNode zonedDateNode = rootNode.get("zonedDate");
assertEquals("zonedDate date should be equals", zonedDate.format(DateTimeFormatter.ISO_ZONED_DATE_TIME), zonedDateNode.textValue());
}
测试失败,打印调试日志
{
"zonedDate":"2015-08-15T11:40:10.100+08:00[Asia/Shanghai]",
"localDate":"2015-08-15T11:40:10.100",
"offsetDate":"2015-08-15T11:40:10.1+08:00"
}
zonedDate 和 localDate 微秒以 00 结尾,但 offsetDate 不是。并且date.format也得到不同的结果,其中微秒不以00结尾。
format、toString、json文本的打印结果
LocalDateTime format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)@2015-08-15T11:40:10.1
LocalDateTime toString @2015-08-15T11:40:10.100
LocalDateTime serialized json node text @2015-08-15T11:40:10.100
OffsetDateTime format(DateTimeFormatter.ISO_OFFSET_DATE_TIME)@2015-08-15T11:40:10.1+08:00
OffsetDateTime toString @2015-08-15T11:40:10.100+08:00
OffsetDateTime serialized json node text @2015-08-15T11:40:10.1+08:00
ZonedDateTime format(DateTimeFormatter.ISO_ZONED_DATE_TIME)@2015-08-15T11:40:10.1+08:00[Asia/Shanghai]
ZonedDateTime toString @2015-08-15T11:40:10.100+08:00[Asia/Shanghai]
ZonedDateTime serialized json node text @2015-08-15T11:40:10.100+08:00[Asia/Shanghai]
- 看来toString结果应该是 jackson 序列化中所需的结果,在上面的日志记录中,OffsetDateTime json节点微秒文本应该以00结尾强> .
- 为什么格式方法结果省略结尾00?
完整的示例代码可以在我的github.com找到。
最佳答案
作为解决方法,我添加了自己的序列化器:
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
SimpleModule module = new SimpleModule();
module.addSerializer(ZonedDateTime.class, new JsonSerializer<ZonedDateTime>() {
@Override
public void serialize(ZonedDateTime zonedDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
jsonGenerator.writeString(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZZZ").format(zonedDateTime));
}
});
objectMapper.registerModule(module);
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
关于jackson - Java 8 DateTime 序列化和 Jackson JSR 310,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32026837/