web-dev-qa-db-ja.com

JacksonはISO 8601形式の日時をJava 8 Instantにデシリアライズします

Jacksonを使用してISO8601形式の日付をJava8 Instantにデシリアライズしようとしています。 JavaTimeModuleをObjectMapperに登録し、WRITE_DATES_AS_TIMESTAMPSをオフにしました。

ただし、2016-03-28T19:00:00.000 + 01:00を逆シリアル化しようとすると、JavaTimeModuleはUTCタイムゾーンオフセット(たとえば2016-03-28T18:00)でフォーマットされた日時のみを逆シリアル化するため、動作しません。 :00.000Z)。次に、次のように@JsonFormatアノテーションを使用してみました。

@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss.SSSZ", timezone = "UTC")

そしてこのように:

@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss.SSSZ", timezone = JsonFormat.DEFAULT_TIMEZONE)

ただし、これらのどちらも動作せず、例外が発生します。

com.fasterxml.jackson.databind.JsonMappingException: Unsupported field: YearOfEra (through reference chain: org.example.Article["date"])

これは、タイムゾーンパラメータが無視され、タイムフォーマッタがタイムゾーンなしでインスタントをフォーマットする方法を知らないことを意味します。

UTCタイムゾーンオフセットにないISO8601文字列をJava 8ジャクソンとJavaTimeModuleを使用して、カスタムデシリアライザーを作成せずにインスタント化する方法はありますか?

33
Kresimir Nesek

ModellクラスのXXXを介して明示的なタイムゾーンを設定する必要があります。

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
private Date date;

(参照: https://docs.Oracle.com/javase/7/docs/api/Java/text/SimpleDateFormat.html

31
Meiko Rachimow

DateオブジェクトをISO-8601にシリアル化する場合、パターンをまったく指定する必要はありません-ISO-8601がデフォルトのパターンです。 JsonFormat Java doc

一般的な用途には、代替表現の選択が含まれます-たとえば、日付を数値としてシリアル化するか(Javaタイムスタンプ)または文字列(ISO-8601互換の時刻値など)-また、pattern()プロパティで正確な詳細を設定します。

[エンファサシス鉱山]上記のテキストから、shape = STRINGはISO-8601形式を意味しますが、patternプロパティを使用して他のものを選択できます。

私の経験では、これは常にUTC日付形式(タイムゾーンは+0000)、これはmy VM(オペレーティングシステムのクロックがUTCに設定されていない場合でも)のデフォルトのタイムゾーンである可能性があります).

2
Guss

これは別のパターンであるため、フォーマット「Z」は「+01:00」では機能しません。 JsonFormatはSimpleDateFormatパターンを使用しています。 大文字の「Z」は厳密なRFC 822のみを表します。コロンのない「+0100」のような構文を使用する必要があります。

参照: ISO 8601:2004SimpleDateFormatパターン

ジャクソン2.9.8(これを書いている現在のもの)では、Dateの代わりにInstantを使用することをお勧めします。

依存関係を追加する必要があります。

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.9.8</version>
</dependency> 

また、モジュールを登録し、SerializationFeature.WRITE_DATES_AS_TIMESTAMPSをfalseに構成します。

new ObjectMapper()
                .findAndRegisterModules()
                .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

Jackson8 for Java8の詳細はこちら: https://github.com/FasterXML/jackson-modules-Java8

1
zoomout