Ich habe ein Datumsformat von der API wie folgt:
"start_time": "2015-10-1 3:00 PM GMT+1:00"
Welches ist JJJJ-TT-MM HH: MM am / pm GMT Zeitstempel. Ich ordne diesen Wert einer Datumsvariablen in POJO zu. Offensichtlich zeigt es Konvertierungsfehler.
Ich möchte 2 Dinge wissen:
- Welche Formatierung muss ich verwenden, um die Konvertierung mit Jackson durchzuführen? Ist Datum ein guter Feldtyp dafür?
- Gibt es im Allgemeinen eine Möglichkeit, die Variablen zu verarbeiten, bevor sie von Jackson Objektmitgliedern zugeordnet werden? So etwas wie das Ändern des Formats, der Berechnungen usw.
Date
Klasse nicht mehr verwenden . java.time, die moderne Java-API für Datum und Uhrzeit, hat sie vor fast 5 Jahren ersetzt. Verwenden Sie es und FasterXML / jackson-modules-java8 .Antworten:
Date
ist ein feiner Feldtyp dafür. Sie können die JSON-Analyse ziemlich einfach machen, indem Sie Folgendes verwendenObjectMapper.setDateFormat
:Ja. Sie haben einige Optionen, einschließlich der Implementierung einer benutzerdefinierten Option
JsonDeserializer
, zJsonDeserializer<Date>
. B. Erweiterung . Dies ist ein guter Anfang.quelle
LocalDateTime
oderZonedDateTime
stattDate
? DaDate
es grundsätzlich veraltet ist (oder zumindest viele seiner Methoden), möchte ich diese Alternativen verwenden.java.util.Date
ausdrücklich erwähnt wird, möchte ich darauf hinweisen, dass dies nicht funktioniert.java.sql.Date.
Siehe auch meine Antwort unten.Seit Jackson v2.0 können Sie die Annotation @JsonFormat direkt für Objektmitglieder verwenden.
quelle
@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", timezone="GMT")
Natürlich gibt es eine automatisierte Methode namens Serialisierung und Deserialisierung, die Sie mit bestimmten Anmerkungen ( @JsonSerialize , @JsonDeserialize ) definieren können, wie auch von pb2q erwähnt.
Sie können sowohl java.util.Date als auch java.util.Calendar ... und wahrscheinlich auch JodaTime verwenden.
Die @ JsonFormat-Annotationen funktionierten bei mir nicht wie gewünscht ( die Zeitzone wurde auf einen anderen Wert eingestellt) während der Deserialisierung (die Serialisierung funktionierte perfekt):
Sie müssen einen benutzerdefinierten Serializer und einen benutzerdefinierten Deserializer anstelle der Annotation @JsonFormat verwenden, wenn Sie ein vorhergesagtes Ergebnis wünschen. Ich habe hier ein wirklich gutes Tutorial und eine Lösung gefunden http://www.baeldung.com/jackson-serialize-dates
Es gibt Beispiele für Datum Felder aber ich brauchte für Kalender Felder so hier ist meine Umsetzung :
Die Serializer- Klasse:
Die Deserializer- Klasse:
und die Verwendung der oben genannten Klassen:
Unter Verwendung dieser Implementierung ergibt die Ausführung des Serialisierungs- und Deserialisierungsprozesses nacheinander den Ursprungswert.
Nur mit der Annotation @JsonFormat liefert die Deserialisierung ein anderes Ergebnis. Ich denke, aufgrund der Standardeinstellung für die interne Zeitzone der Bibliothek können Sie diese mit den Annotationsparametern nicht ändern (das war auch meine Erfahrung mit den Versionen Jackson Library 2.5.3 und 2.6.3).
quelle
Nur ein vollständiges Beispiel für eine Spring-Boot- Anwendung im
RFC3339
Datetime-Formatquelle
Hinzufügen von Zeichen wie T und Z zu Ihrem Datum
Ausgabe
quelle
Ich arbeite für mich. SpringBoot.
Ausgabe:
quelle
Aufbauend auf der sehr hilfreichen Antwort von @ miklov-kriven hoffe ich, dass sich diese beiden zusätzlichen Überlegungen für jemanden als hilfreich erweisen:
(1) Ich finde es eine gute Idee, Serializer und De-Serializer als statische innere Klassen in dieselbe Klasse aufzunehmen. Hinweis: Verwenden von ThreadLocal für die Thread-Sicherheit von SimpleDateFormat.
(2) Alternativ zur Verwendung von Annotationen @JsonSerialize und @JsonDeserialize für jedes einzelne Klassenmitglied können Sie auch die Standard-Serialisierung von Jackson überschreiben, indem Sie die benutzerdefinierte Serialisierung auf Anwendungsebene anwenden. Dies bedeutet, dass alle Klassenmitglieder vom Typ Datum von Jackson serialisiert werden Verwenden dieser benutzerdefinierten Serialisierung ohne explizite Anmerkung für jedes Feld. Wenn Sie beispielsweise Spring Boot verwenden, haben Sie folgende Möglichkeiten:
quelle
Wenn jemand Probleme mit der Verwendung eines benutzerdefinierten Datumsformats für java.sql.Date hat, ist dies die einfachste Lösung:
(Diese SO-Antwort hat mir viel Ärger erspart: https://stackoverflow.com/a/35212795/3149048 )
Jackson verwendet den SqlDateSerializer standardmäßig für java.sql.Date. Derzeit berücksichtigt dieser Serializer jedoch nicht das Datumsformat. Weitere Informationen finden Sie in diesem Problem: https://github.com/FasterXML/jackson-databind/issues/1407 . Die Problemumgehung besteht darin, einen anderen Serializer für java.sql.Date zu registrieren, wie im Codebeispiel gezeigt.
quelle
Ich möchte darauf hinweisen, dass das Setzen eines
SimpleDateFormat
ähnlichen wie in der anderen Antwort beschriebenen nur für ein funktioniert, vonjava.util.Date
dem ich annehme, dass es in der Frage gemeint ist. Aber fürjava.sql.Date
den Formatierer funktioniert das nicht. In meinem Fall war es nicht sehr offensichtlich, warum der Formatierer nicht funktionierte, da in dem Modell, das serialisiert werden sollte, das Feld tatsächlich a warjava.utl.Date
, das eigentliche Objekt jedoch ajava.sql.Date
. Dies ist möglich, weilDas ist also tatsächlich gültig
Wenn Sie sich also fragen, warum Ihr Datumsfeld nicht richtig formatiert ist, stellen Sie sicher, dass das Objekt wirklich ein Objekt ist
java.util.Date
.Hier wird auch erwähnt, warum die Handhabung
java.sql.Date
nicht hinzugefügt wird.quelle
Date
Klassen hingewiesen haben . Heutzutage sollte man aber auch keinen von ihnen habenSimpleDateFormat
. java.time, die moderne Java-API für Datum und Uhrzeit, hat sie vor fast 5 Jahren ersetzt. Verwenden Sie es und FasterXML / jackson-modules-java8 .