使用しているサービスの逆シリアル化中に使用するクラスに、次のフィールドがあります。
private ZonedDateTime transactionDateTime;
私が消費しているサービスは、次のパターンを使用してDateまたはDateTimeを返す場合があります。yyyy-MM-dd'T'HH:mm:ss.SSSZ
サービスが返すものの2つの例を挙げましょう:
前者は正常に機能しますが、後者では逆シリアル化中に次の例外がスローされます。
Java.time.format.DateTimeParseException:テキスト '2015-11-18T00:00:00.000 +0200'をインデックス23で解析できませんでした
私が使用しています。
これにはカスタムの逆シリアル化クラスが必要ですか?
コードの前半では、_@JsonFormat
_アノテーション付きのフィールドを使用していましたが、JavaDocsが提案するように、シリアル化のみを目的としていると思ったので、それを削除しました。
その注釈を追加し直す必要があることが判明しました。そして本当の問題は、サードパーティのサービス応答が実際に間違っていた(XMLにラッパー要素がなかった)ため、逆シリアル化が失敗したことでした。エラーは次のとおりです。
com.fasterxml.jackson.databind.JsonMappingException:タイプ[単純なタイプ、クラスcom.foo.bar.adapter.john.model.account.UserAccount]の値を文字列値からインスタンス化できません( '2015-11-18T00:00: 00.000 + 0200 ');単一文字列のコンストラクタ/ファクトリメソッドはありません
フィールドは次のように記述されます。
_@JsonFormat(pattern = Constants.DATETIME_FORMAT)
@JacksonXmlProperty(localName = "transactionDate")
private ZonedDateTime transactionDateTime;
_
また、オブジェクトはコレクションにラップされているため、このフィールドのクラスに@JsonRootName("transaction")
を追加する必要がありました。
次のような注釈を使用できます。
@JsonSerialize(using = MyCustomJsonDateSerializer.class)
または
@JsonDeserialize(using = MyCustomJsonDateDeserializer.class)
ジャクソンが日付を解析する方法をカスタマイズします。これらのカスタムシリアライザーとデシリアライザーは、JsonSerializerとJsonDeserializerを拡張する必要があります。例えば:
public class MyCustomJsonDateSerializer extends JsonSerializer<Date> {
@Override
public void serialize(Date date, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
jgen.writeString(date != null ? ISODateTimeFormat.dateTime().print(new DateTime(date)) : null);
}
}
jackson deserializeは、デフォルトでタイムゾーン情報をバイパスし、ctxタイムゾーンを使用してオーバーライドします。これにより、すべてのISO8601はUTCで終了します。
この機能は、春の春にいる場合はオフにすることができます。jackson.deserialization.ADJUST_DATES_TO_CONTEXT_TIME_ZONE= false