2

Spring Boot アプリケーションで Java 8 DateTime と Jackson jsr 310 のサポートを使用しています。

SerializationFeature.WRITE_DATES_AS_TIMESTAMPSを無効 にして、Jackson に localDatetime を int 配列ではなく文字列にシリアル化するよう強制しました。

しかし、datetime マイクロ秒または nonaseconds が 0 の終わりであるときに、奇妙なフォーマットの問題が見つかりました。シリアル化された結果はdate.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)と等しい可能性があると思いますが、そうではなく、フォーマットメソッドがゼロを省略しました。

サンプル テスト コードを完成させます。

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"
}

zonedDatelocalDate のマイクロ秒は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]
  1. toStringの結果はJackson シリアライゼーションで望ましい結果になるはずです。上記のロギングでは、OffsetDateTime json node microseconds text は00で終わる必要があります。
  2. format メソッドの結果で末尾の00が省略されるのはなぜですか?

完全なサンプル コードは、私の github.com から見つけることができます。

angular-springmvc-サンプルブート

ISODateTest

4

3 に答える 3

0

ObjectMapper を構成するために私が行ったことは次のとおりです。

@Configuration
public class JacksonConfiguration {

  @Bean
  public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
    ObjectMapper objectMapper = builder.build();
    objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
    objectMapper.configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, false);
    return objectMapper;
  }
}
于 2016-08-28T15:31:51.020 に答える