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;
}
ZonedDateTime
がISO形式に従ってフォーマットされることを期待していましたが、代わりに次のようなクラスの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-jetty
を除くspring-boot-starter-Tomcat
アプリケーションがあります。
なぜジャクソンはSpring Bootでこのように振る舞いますか?
**更新**
これを解決する方法をステップバイステップガイドで探している人のために、私は質問をした後にこれを見つけました: http://lewandowski.io/2016/02/formatting-Java-time-with-spring-boot- using-json /
ライブラリがあります jackson-datatype-jsr31 。それを試してみてください。
このライブラリは、新しい日時APIをカバーし、ZonedDateTime
のシリアライザーも含まれています。
必要なのはJavaTimeModule
を追加するだけです:
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
[〜#〜] update [〜#〜]
日時を ISO-8601
文字列に変換するには、 WRITE_DATES_AS_TIMESTAMPS
機能を無効にする必要があります。 ObjectMapper
Beanをオーバーライドするか、 アプリケーションプロパティ を使用することで簡単に実行できます。
spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS = false
SpringBootの自動設定機能に依存しない場合-spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS = false
プロパティを設定ファイルに-または何らかの理由でObjectMapper
インスタンスを手動で作成します。この機能は、次のようにプログラムで無効にできます。
ObjectMapper m = new ObjectMapper();
m.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
これはジャクソン用です2.8.7
答えはすでに上で述べたが、情報が欠けていると思う。 Java ZonedDateTimeだけでなく、多くの形式の8つのタイムスタンプ)を解析する場合。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でオブジェクトマッパーをグローバルに構成できることに注意してください。カスタム(デ)シリアライザーを登録せずに、フィールドの注釈としてこれを行うクリーンな方法をまだ見つけていません。