Wie verwende ich Jackson JSON Mapper mit Java 8 LocalDateTime?
org.codehaus.jackson.map.JsonMappingException: Wert vom Typ [einfacher Typ, Klasse java.time.LocalDateTime] kann nicht aus JSON String instanziiert werden; kein Single-String-Konstruktor / Factory-Methode (über die Referenzkette: MyDTO ["field1"] -> SubDTO ["date"])
Antworten:
Hier müssen keine benutzerdefinierten Serializer / Deserializer verwendet werden. Verwenden Sie das datetime-Modul von jackson-modules-java8 :
Dieses Modul bietet Unterstützung für einige Klassen:
quelle
registerModule(new JSR310Module())
oderfindAndRegisterModules()
. Siehe github.com/FasterXML/jackson-datatype-jsr310 und hier erfahrenOffsetDateTime
@Test
public void testJacksonOffsetDateTimeDeserializer() throws IOException {
ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule());
String json = "\"2015-10-20T11:00:00-8:30\"";
mapper.readValue(json, OffsetDateTime.class);
}
objectMapper.registerModule(new JavaTimeModule());
. Sowohl bei der Serialisierung als auch bei der Deserialisierung.Update: Diese Antwort aus historischen Gründen hinterlassen, aber ich empfehle sie nicht. Bitte beachten Sie die oben akzeptierte Antwort.
Weisen Sie Jackson an, mithilfe Ihrer benutzerdefinierten [de] Serialisierungsklassen zuzuordnen:
Stellen Sie benutzerdefinierte Klassen bereit:
zufällige Tatsache: Wenn ich über Klassen verschachtele und sie nicht statisch mache, ist die Fehlermeldung seltsam:
org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json;charset=UTF-8' not supported
quelle
LocalDateTimeSerializer
undLocalDateTimeDeserializer
Wenn Sie die ObjectMapper-Klasse von schnellerxml verwenden, versteht ObjectMapper die LocalDateTime-Klasse standardmäßig nicht. Daher müssen Sie Ihrem Gradle / Maven eine weitere Abhängigkeit hinzufügen:
Jetzt müssen Sie die von dieser Bibliothek angebotene Datentypunterstützung in Ihrem Objectmapper-Objekt registrieren. Dies kann folgendermaßen erfolgen:
Jetzt können Sie in Ihrem jsonString Ihr java.LocalDateTime-Feld wie folgt einfügen:
Auf diese Weise funktioniert die Konvertierung Ihrer Json-Datei in Java-Objekte einwandfrei. Sie können die Datei folgendermaßen lesen:
quelle
findAndRegisterModules()
war ein kritisches Stück, das mir beim Bau einesObjectMapper
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
Diese Maven-Abhängigkeit löst Ihr Problem:
Eine Sache, mit der ich zu kämpfen hatte, war, dass die Zeitzone von ZonedDateTime während der Deserialisierung auf GMT geändert wurde. Es stellte sich heraus, dass Jackson es standardmäßig durch eines aus dem Kontext ersetzt. Um die Zone beizubehalten, muss diese 'Funktion' deaktiviert werden.
quelle
DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE
ich deaktivieren hatte auchSerializationFeature.WRITE_DATES_AS_TIMESTAMPS
für alles anfangen zu arbeiten , wie es sollte.Ich hatte ein ähnliches Problem bei der Verwendung von Spring Boot . Mit Spring Boot 1.5.1.RELEASE musste ich nur die Abhängigkeit hinzufügen:
quelle
Wenn Sie Jersey verwenden, müssen Sie die Maven-Abhängigkeit (jackson-datatype-jsr310) wie von den anderen vorgeschlagen hinzufügen und Ihre Objekt-Mapper-Instanz wie folgt registrieren:
Wenn Sie Jackson in Ihren Ressourcen registrieren, müssen Sie diesen Mapper wie folgt hinzufügen:
quelle
Wenn Sie nicht verwenden können ,
jackson-modules-java8
für welchen Gründen auch immer können Sie die (De-) serialisiert werden die Instant - Feld alslong
mit@JsonIgnore
und@JsonGetter
&@JsonSetter
:Beispiel:
ergibt
quelle
Ich benutze dieses Zeitformat:
"{birthDate": "2018-05-24T13:56:13Z}"
um von json in java.time.Instant zu deserialisieren (siehe Screenshot)quelle
Dies ist nur ein Beispiel für die Verwendung in einem Komponententest, den ich gehackt habe, um dieses Problem zu beheben. Die Hauptzutaten sind
mapper.registerModule(new JavaTimeModule());
<artifactId>jackson-datatype-jsr310</artifactId>
Code:
quelle
Wenn Sie Spring Boot verwenden und dieses Problem mit OffsetDateTime haben, müssen Sie die registerModules verwenden, wie oben von @greperror (beantwortet am 28. Mai 16 um 13:04 Uhr) beantwortet. Beachten Sie jedoch, dass es einen Unterschied gibt. Die erwähnte Abhängigkeit muss nicht hinzugefügt werden, da ich vermute, dass Spring Boot sie bereits hat. Ich hatte dieses Problem mit Spring Boot und es funktionierte für mich, ohne diese Abhängigkeit hinzuzufügen.
quelle
Sie können dies in Ihrer
application.yml
Datei festlegen, um die Sofortzeit aufzulösen. Dies ist die Datums-API in Java8:quelle
Für diejenigen, die verwenden Spring Boot 2.x verwenden
Es ist nicht erforderlich, die oben genannten Schritte auszuführen. Java 8 LocalDateTime wird standardmäßig serialisiert / de-serialisiert. Ich musste all das in 1.x machen, aber mit Boot 2.x funktioniert es nahtlos.
Siehe auch diese Referenz JSON Java 8 LocalDateTime-Format in Spring Boot
quelle
Wenn jemand Probleme bei der Verwendung hat
SpringBoot
hat, habe ich das Problem behoben, ohne neue Abhängigkeiten hinzuzufügen.In
Spring 2.1.3
Jackson wird erwartet, dass Datumszeichenfolgen2019-05-21T07:37:11.000
in diesemyyyy-MM-dd HH:mm:ss.SSS
Format de-serialisiert werdenLocalDateTime
. Stellen Sie sicher, dass Datumszeichenfolge Datum und Uhrzeit mitT
nicht mit trenntspace
. Sekunden (ss
) und Millisekunden (SSS
) können weggelassen werden.quelle
Wenn Sie Fastjson verwenden möchten, können Sie Ihr Problem lösen. Beachten Sie die Version
quelle
Wenn Sie dieses Problem aufgrund von GraphQL Java Tools haben und versuchen, ein Java
Instant
aus einer Datumszeichenfolge zu marshallen, müssen Sie Ihren SchemaParser so einrichten, dass ein ObjectMapper mit bestimmten Konfigurationen verwendet wird:Fügen Sie in Ihrer GraphQLSchemaBuilder-Klasse ObjectMapper ein und fügen Sie die folgenden Module hinzu:
und fügen Sie es den Optionen hinzu:
Siehe https://github.com/graphql-java-kickstart/graphql-spring-boot/issues/32
quelle
Wenn Sie Jackson Serializer verwenden , können Sie die Datumsmodule folgendermaßen verwenden:
quelle