Comment utiliser le mappeur Jackson JSON avec Java 8 LocalDateTime?
org.codehaus.jackson.map.JsonMappingException: impossible d'instancier la valeur de type [type simple, classe java.time.LocalDateTime] à partir de la chaîne JSON; pas de constructeur / méthode d'usine à chaîne unique (via la chaîne de référence: MyDTO ["field1"] -> SubDTO ["date"])
Réponses:
Il n'est pas nécessaire d'utiliser ici des sérialiseurs / désérialiseurs personnalisés. Utilisez le module datetime de jackson-modules-java8 :
Ce module ajoute le support de plusieurs classes:
la source
registerModule(new JSR310Module())
oufindAndRegisterModules()
. Voir github.com/FasterXML/jackson-datatype-jsr310 et voici comment personnaliser votre objet mappeur si vous utilisez le framework Spring: stackoverflow.com/questions/7854030/…OffsetDateTime
@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());
. Tant sur la sérialisation que sur la désérialisation.Mise à jour: laisser cette réponse pour des raisons historiques, mais je ne la recommande pas. Veuillez voir la réponse acceptée ci-dessus.
Dites à Jackson de mapper à l'aide de vos classes de dé-sérialisation personnalisées:
fournir des classes personnalisées:
fait aléatoire: si je niche au-dessus des classes et ne les rend pas statiques, le message d'erreur est bizarre:
org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json;charset=UTF-8' not supported
la source
LocalDateTimeSerializer
etLocalDateTimeDeserializer
Si vous utilisez la classe ObjectMapper de fastxml, par défaut ObjectMapper ne comprend pas la classe LocalDateTime, vous devez donc ajouter une autre dépendance dans votre gradle / maven:
Vous devez maintenant enregistrer le support de type de données offert par cette bibliothèque dans votre objet objectmapper, cela peut être fait en suivant:
Maintenant, dans votre jsonString, vous pouvez facilement mettre votre champ java.LocalDateTime comme suit:
En faisant tout cela, votre conversion de fichier Json en objet Java fonctionnera correctement, vous pouvez lire le fichier en suivant:
la source
findAndRegisterModules()
était une pièce critique qui me manquait lors de la construction d'unObjectMapper
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
Cette dépendance maven résoudra votre problème:
Une chose que j'ai eu du mal à faire est que le fuseau horaire de ZonedDateTime soit modifié en GMT pendant la désérialisation. Il s'est avéré que par défaut jackson le remplace par un autre du contexte. Pour conserver la zone, il faut désactiver cette «fonctionnalité»
la source
DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE
j'ai également dû désactiverSerializationFeature.WRITE_DATES_AS_TIMESTAMPS
pour que tout commence à fonctionner comme il se doit.J'ai eu un problème similaire lors de l'utilisation de Spring Boot . Avec Spring boot 1.5.1.RELEASE, tout ce que j'avais à faire était d'ajouter une dépendance:
la source
Si vous utilisez Jersey, vous devez ajouter la dépendance Maven (jackson-datatype-jsr310) comme les autres l'ont suggéré et enregistrer votre instance de mappeur d'objet comme suit:
Lorsque vous enregistrez Jackson dans vos ressources, vous devez ajouter ce mappeur comme suit:
la source
Si vous ne pouvez pas utiliser
jackson-modules-java8
pour quelque raison que ce soit, vous pouvez (dé-) sérialiser le champ instantané enlong
utilisant@JsonIgnore
et@JsonGetter
&@JsonSetter
:Exemple:
les rendements
la source
J'utilise ce format d'heure:
"{birthDate": "2018-05-24T13:56:13Z}"
pour désérialiser de json en java.time.Instant (voir capture d'écran)la source
Ceci est juste un exemple comment l'utiliser dans un test unitaire que j'ai piraté pour déboguer ce problème. Les ingrédients clés sont
mapper.registerModule(new JavaTimeModule());
<artifactId>jackson-datatype-jsr310</artifactId>
Code:
la source
Vous pouvez définir cela dans votre
application.yml
fichier pour résoudre l'heure instantanée, qui est l'API Date dans java8:la source
Si vous utilisez Spring Boot et que vous rencontrez ce problème avec OffsetDateTime, vous devez utiliser les registerModules comme indiqué ci-dessus par @greperror (répondu le 28 mai 16 à 13:04), mais notez qu'il existe une différence. La dépendance mentionnée n'a pas besoin d'être ajoutée car je suppose que Spring Boot l'a déjà. J'avais ce problème avec Spring Boot et cela a fonctionné pour moi sans ajouter cette dépendance.
la source
Pour ceux qui utilisent Spring Boot 2.x
Il n'est pas nécessaire de faire ce qui précède - Java 8 LocalDateTime est sérialisé / désérialisé hors de la boîte. J'ai dû faire tout ce qui précède en 1.x, mais avec Boot 2.x, cela fonctionne de manière transparente.
Voir également cette référence Format JSON Java 8 LocalDateTime dans Spring Boot
la source
Si quelqu'un a un problème lors de l'utilisation,
SpringBoot
voici comment j'ai résolu le problème sans ajouter de nouvelle dépendance.In
Spring 2.1.3
Jackson s'attend à ce que la chaîne de date2019-05-21T07:37:11.000
dans ceyyyy-MM-dd HH:mm:ss.SSS
format se désérialiseLocalDateTime
. Assurez-vous que la chaîne de date sépare la date et l'heure avecT
pas avecspace
. secondes (ss
) et millisecondes (SSS
) peuvent être omises.la source
Si vous utilisez Jackson Serializer , voici une façon d'utiliser les modules de date:
la source
Si vous envisagez d'utiliser fastjson, vous pouvez résoudre votre problème, notez la version
la source
Si vous rencontrez ce problème à cause des outils Java GraphQL et que vous essayez de marshaler un Java à
Instant
partir d'une chaîne de date, vous devez configurer votre SchemaParser pour utiliser un ObjectMapper avec certaines configurations:Dans votre classe GraphQLSchemaBuilder, injectez ObjectMapper et ajoutez ces modules:
et l'ajouter aux options:
Voir https://github.com/graphql-java-kickstart/graphql-spring-boot/issues/32
la source