webentwicklung-frage-antwort-db.com.de

Jackson deserialisiert das Datum und die Uhrzeit nach ISO 8601 in Java 8 Instant

Ich versuche, ein mit ISO8601 formatiertes Datum mithilfe von Jackson in Java8 Instant zu deserialisieren. Ich habe JavaTimeModule beim ObjectMapper registriert, WRITE_DATES_AS_TIMESTAMPS deaktiviert.

Wenn jedoch versucht wird, 2016-03-28T19: 00: 00.000 + 01: 00 zu deserialisieren, wird dies nicht funktionieren, da JavaTimeModule anscheinend nur Datumszeiten deserialisiert, die mit UTC-Zeitzonen-Offset formatiert sind (z. B. 2016-03-28T18: 00) : 00.000Z). Ich habe dann versucht, @JsonFormat-Annotation wie folgt zu verwenden:

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

Und so:

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

Keines davon funktioniert jedoch und ich bekomme eine Ausnahme:

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

Dies bedeutet, dass der Parameter der Zeitzone ignoriert wird und der Datumsformatierer nicht weiß, wie ein Instant ohne Zeitzone formatiert wird. 

Gibt es eine Möglichkeit, eine ISO8601-Zeichenfolge zu deserialisieren, die sich nicht in der UTC-Zeitzonenverschiebung zu Java 8 Instant mit Jackson und JavaTimeModule befindet, ohne einen benutzerdefinierten Deserializer zu schreiben?

25
Kresimir Nesek

Sie müssen die explizite Zeitzone in Ihrer Modellklasse über XXX einstellen:

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

(Siehe: https://docs.Oracle.com/javase/7/docs/api/Java/text/SimpleDateFormat.html )

23
Meiko Rachimow

Das Format "Z" funktioniert nicht mit "+01: 00", da dies ein anderes Muster ist. JsonFormat verwendet SimpleDateFormat-Muster. "Z" in Großbuchstaben steht nur für den strengen RFC 822. Sie müssen die folgende Syntax verwenden: "+0100", ohne Doppelpunkt.

Siehe: ISO 8601: 2004 , SimpleDateFormat-Muster

In Jackson 2.9.8 (aktuell, da ich dies schreibe) ist es besser, Instant anstelle von Date zu verwenden. 

Sie müssen eine Abhängigkeit hinzufügen:

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

Registrieren Sie außerdem das Modul und konfigurieren Sie SerializationFeature.WRITE_DATES_AS_TIMESTAMPS auf false.

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

Weitere Informationen zu Jackson für Java8 finden Sie hier: https://github.com/FasterXML/jackson-modules-Java8

1
zoomout

Wenn Sie Date-Objekte in ISO-8601 serialisieren möchten, müssen Sie überhaupt kein Muster angeben - ISO-8601 ist das Standardmuster. Es ist eine Art Erwähnung im JsonFormat Java-Dokument :

Übliche Anwendungen umfassen die Wahl zwischen alternativen Darstellungen - beispielsweise, ob Date als Nummer (Java-Zeitstempel) oder String (z. B. ISO-8601-kompatibler Zeitwert) serialisiert werden soll - oder die genaue Festlegung von Details mit Muster () Eigentum.

[Hervorhebung meines] Sie sollten aus dem obigen Text verstehen, dass die Angabe von shape = STRING ein ISO-8601-Format bedeuten würde, Sie können jedoch mit der pattern-Eigenschaft etwas anderes auswählen.

Meiner Erfahrung nach stellt dies immer ein UTC-Datumsformat dar (wobei die Zeitzone als +0000 dargestellt wird). Dies könnte die Standardzeitzone in meiner VM sein (auch wenn meine Betriebssystemuhr nicht auf UTC eingestellt ist).

0
Guss