Ich habe einen Weg gefunden, es zu tun, ohne einen benutzerdefinierten Deserializer zu schreiben, aber es erfordert einige Modifikationen.
Zuerst akzeptiert die LocalDateDeserializer
eine benutzerdefinierte . Also müssen wir einen Formatierer erstellen, der eine Epoche Millis akzeptiert. Ich tat dies, indem sie die INSTANT_SECONS
und MILLI_OF_SECOND
Felder Beitritt:
// formatter that accepts an epoch millis value
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
// epoch seconds
.appendValue(ChronoField.INSTANT_SECONDS, 1, 19, SignStyle.NEVER)
// milliseconds
.appendValue(ChronoField.MILLI_OF_SECOND, 3)
// create formatter, using UTC as timezone
.toFormatter().withZone(ZoneOffset.UTC);
Ich habe auch die Formatierungs mit UTC-Zone, so wird es nicht von Zeitzonen und Sommerzeit-Änderungen betroffen sein.
Dann habe ich die Deserializer erstellt und registriert in meinem ObjectMapper
:
ObjectMapper mapper = new ObjectMapper();
JavaTimeModule module = new JavaTimeModule();
// add the LocalDateDeserializer with the custom formatter
module.addDeserializer(LocalDate.class, new LocalDateDeserializer(formatter));
mapper.registerModule(module);
Ich musste auch die Anmerkung aus dem birthday
Feld entfernen (da die Annotation die Modulkonfiguration außer Kraft zu setzen scheint):
public class FbProfile {
long id;
// remove @JsonDeserialize annotation
LocalDate birthday;
}
und jetzt die große Frage: wie die DateTimeFormatter
nur String
als Eingabe akzeptiert und die JSON enthält eine Reihe in birthday
Feld, hatte ich das JSON zu ändern:
{
"id" : "1",
"birthday" : "401280850089"
}
Bitte beachte, dass ich birthday
zu einem String
geändert (setzen Sie den Wert zwischen Anführungszeichen).
Damit wird die LocalDate
korrekt von JSON lesen:
FbProfile value = mapper.readValue(json, FbProfile.class);
System.out.println(value.getBirthday()); // 1982-09-19
Hinweise:
- ich keine Möglichkeit, die Nummer direkt an den Formatierer finden könnte passieren (Da es nur
String
als Eingabe benötigt), musste ich die Nummer zu einem String
ändern. Wenn Sie das nicht möchten, müssen Sie sowieso einen benutzerdefinierten Konverter schreiben.
- Sie können
ZoneOffset.UTC
durch eine beliebige Zeitzone ersetzen (sogar ZoneId.systemDefault()
), es hängt davon ab, was Ihre Anwendung benötigt. Aber wie in @Ole V.V.'s comment erzählt, könnte die Zeitzone das Datum ändern.
Bitte beachten Sie, dass die Umwandlung von Millisekunden bis zum Datum zeitzonenabhängig ist. Zum Beispiel entspricht die Zahl in Ihrem Beispiel 1982-09-19T10: 54: 10.089Z, was wiederum gleich 1982-09-18T23: 54: 10.089-11: 00 [Pacific/Midway] ist. –
Vermeiden Sie die altmodische Klasse "Date". Das einzige, was es dir gibt, dass moderne Klassen nicht Ärger sind. Wenn Sie andere Klassen als 'LocalDate' ausprobieren möchten, ist' Instant' die offensichtliche Wahl. –
Haben Sie vor der Nachfrage gesucht? Ich denke, Sie finden vielleicht etwas Inspiration in [dieser Frage: Java 8 LocalDate Jackson Format] (https://stackoverflow.com/questions/28802544/java-8-localdate-jackson-format). –