43

Spring Boot と Jetty を使用した単純なアプリケーションがあります。Java 8 を持つオブジェクトを返す単純なコントローラーがありますZonedDateTime

public class Device {
  // ...
  private ZonedDateTime lastUpdated;

  public Device(String id, ZonedDateTime lastUpdated, int course, double latitude, double longitude) {
    // ...
    this.lastUpdated = lastUpdated;
    // ...
  }

  public ZonedDateTime getLastUpdated() {
    return lastUpdated;
  }
}

私のRestController中で私は単に持っています:

@RequestMapping("/devices/")
public @ResponseBody List<Device> index() {
  List<Device> devices = new ArrayList<>();
  devices.add(new Device("321421521", ZonedDateTime.now(), 0, 39.89011333, 24.438176666));

  return devices;
}

ZonedDateTimeISO 形式に従ってフォーマットされることを期待していましたが、代わりに、次のようなクラスの JSON ダンプ全体を取得しています。

"lastUpdated":{"offset":{"totalSeconds":7200,"id":"+02:00","rules":{"fixedOffset":true,"transitionRules":[],"transitions":[]}},"zone":{"id":"Europe/Berlin","rules":{"fixedOffset":false,"transitionRules":[{"month":"MARCH","timeDefinition":"UTC","standardOffset":{"totalSeconds":3600,"id":"+01:00","rules":{"fixedOffset":true,"transitionRules":[],"transitions":[]}},"offsetBefore":{"totalSeconds":3600,"id":"+01:00","rules":{"fixedOffset":true,"transitionRules":[],"transitions":[]}},"offsetAfter":{"totalSeconds":7200,"id":"+02:00", ...

を使用して除外するspring-boot-starter-webアプリケーションがあります。spring-boot-starter-jettyspring-boot-starter-tomcat

Spring BootでJacksonがこのように振る舞うのはなぜですか?

** アップデート **

これを解決するための完全なステップバイステップガイドを探している人のために、質問をした後にこれを見つけました: http://lewandowski.io/2016/02/formatting-java-time-with-spring-boot-using-json/

4

4 に答える 4

7

答えはすでに上で言及されていますが、いくつかの情報が欠けていると思います。Java 8 タイムスタンプをさまざまな形式 (ZonedDateTime だけでなく) で解析しようとしている人向け。POMに の最新バージョンが必要でjackson-datatype-jsr310、次のモジュールが登録されています。

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

このコードをテストするには

@Test
void testSeliarization() throws IOException {
    String expectedJson = "{\"parseDate\":\"2018-12-04T18:47:38.927Z\"}";
    MyPojo pojo = new MyPojo(ZonedDateTime.parse("2018-12-04T18:47:38.927Z"));

    // serialization
    assertThat(objectMapper.writeValueAsString(pojo)).isEqualTo(expectedJson);

    // deserialization
    assertThat(objectMapper.readValue(expectedJson, MyPojo.class)).isEqualTo(pojo);
}

これを実現するために、Spring または dropwizard でオブジェクト マッパーをグローバルに構成できることに注意してください。カスタム(デ)シリアライザーを登録せずに、フィールドの注釈としてこれを行うクリーンな方法をまだ見つけていません。

于 2018-12-06T17:47:57.753 に答える