J'ai un format de date provenant de l'API comme celui-ci:
"start_time": "2015-10-1 3:00 PM GMT+1:00"
Qui est AAAA-JJ-MM HH: MM am / pm GMT horodatage. Je mappe cette valeur à une variable de date dans POJO. De toute évidence, il affiche une erreur de conversion.
J'aimerais savoir 2 choses:
- Quel format dois-je utiliser pour effectuer une conversion avec Jackson? La date est-elle un bon type de champ pour cela?
- En général, existe-t-il un moyen de traiter les variables avant qu'elles ne soient mappées aux membres Object par Jackson? Quelque chose comme, changer le format, les calculs, etc.
Date
classe. java.time, l'API Java de date et d'heure moderne, l' a remplacé il y a près de 5 ans. Utilisez-le et FasterXML / jackson-modules-java8 .Réponses:
Date
est un type de champ fin pour cela. Vous pouvez rendre l'analyse JSON assez facilement en utilisantObjectMapper.setDateFormat
:Oui. Vous avez quelques options, y compris l'implémentation d'un custom
JsonDeserializer
, par exemple l'extensionJsonDeserializer<Date>
. C'est un bon début.la source
LocalDateTime
ou à laZonedDateTime
place deDate
? Étant donné queDate
c'est fondamentalement obsolète (ou du moins beaucoup de ses méthodes), j'aimerais utiliser ces alternatives.java.util.Date
explicitement, je tiens à souligner que cela ne fonctionne pas pourjava.sql.Date.
Voir également ma réponse ci-dessous.Depuis Jackson v2.0, vous pouvez utiliser l'annotation @JsonFormat directement sur les membres Object;
la source
@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", timezone="GMT")
Bien sûr, il existe une méthode automatisée appelée sérialisation et désérialisation et vous pouvez la définir avec des annotations spécifiques ( @JsonSerialize , @JsonDeserialize ) comme mentionné par pb2q.
Vous pouvez utiliser à la fois java.util.Date et java.util.Calendar ... et probablement JodaTime également.
Les annotations @JsonFormat n'ont pas fonctionné pour moi comme je le voulais (il a ajusté le fuseau horaire à une valeur différente) lors de la désérialisation (la sérialisation a parfaitement fonctionné):
Vous devez utiliser un sérialiseur personnalisé et un désérialiseur personnalisé au lieu de l'annotation @JsonFormat si vous voulez un résultat prédit. J'ai trouvé un très bon tutoriel et une solution ici http://www.baeldung.com/jackson-serialize-dates
Il existe des exemples pour les champs Date mais j'avais besoin pour les champs Calendrier , voici donc mon implémentation :
La classe de sérialiseur :
La classe deserializer :
et l'utilisation des classes ci-dessus:
En utilisant cette implémentation, l'exécution du processus de sérialisation et de désérialisation donne consécutivement la valeur d'origine.
En utilisant uniquement l'annotation @JsonFormat, la désérialisation donne un résultat différent Je pense qu'en raison de la configuration par défaut du fuseau horaire interne de la bibliothèque, ce que vous ne pouvez pas changer avec les paramètres d'annotation (c'était également mon expérience avec les versions 2.5.3 et 2.6.3 de la bibliothèque Jackson).
la source
Juste un exemple complet d' application Spring Boot avec le
RFC3339
format datetimela source
Pour ajouter des caractères tels que T et Z dans votre date
production
la source
Travailler pour moi. SpringBoot.
production:
la source
En m'appuyant sur la réponse très utile de @ miklov-kriven, j'espère que ces deux points de considération supplémentaires seront utiles à quelqu'un:
(1) Je trouve que c'est une bonne idée d'inclure le sérialiseur et le désérialiseur en tant que classes internes statiques dans la même classe. NB, en utilisant ThreadLocal pour la sécurité des threads de SimpleDateFormat.
(2) Au lieu d'utiliser les annotations @JsonSerialize et @JsonDeserialize sur chaque membre de classe individuel, vous pouvez également envisager de remplacer la sérialisation par défaut de Jackson en appliquant la sérialisation personnalisée au niveau de l'application, c'est-à-dire que tous les membres de classe de type Date seront sérialisés par Jackson en utilisant cette sérialisation personnalisée sans annotation explicite sur chaque champ. Si vous utilisez Spring Boot par exemple, une façon de le faire serait la suivante:
la source
Si quelqu'un a des problèmes avec l'utilisation d'un format de date personnalisé pour java.sql.Date, voici la solution la plus simple:
(Cette réponse SO m'a évité beaucoup de problèmes: https://stackoverflow.com/a/35212795/3149048 )
Jackson utilise le SqlDateSerializer par défaut pour java.sql.Date, mais actuellement, ce sérialiseur ne prend pas en compte le format de date, voir ce problème: https://github.com/FasterXML/jackson-databind/issues/1407 . La solution de contournement consiste à enregistrer un sérialiseur différent pour java.sql.Date, comme indiqué dans l'exemple de code.
la source
Je tiens à souligner que la définition d'un
SimpleDateFormat
comme décrit dans l'autre réponse ne fonctionne que pour unjava.util.Date
qui, je suppose, est destiné à la question. Mais pourjava.sql.Date
le formateur ne fonctionne pas. Dans mon cas, il n'était pas très évident de savoir pourquoi le formateur ne fonctionnait pas parce que dans le modèle qui devait être sérialisé, le champ était en fait unjava.utl.Date
mais l'objet réel a fini par être unjava.sql.Date
. Ceci est possible carDonc c'est en fait valable
Donc, si vous vous demandez pourquoi votre champ Date n'est pas correctement formaté, assurez-vous que l'objet est vraiment un
java.util.Date
.Voici également pourquoi la manipulation
java.sql.Date
ne sera pas ajoutée.la source
Date
classes différentes . De nos jours, on ne devrait pas non plus aucun d'entre euxSimpleDateFormat
. java.time, l'API Java de date et d'heure moderne, les a remplacés il y a près de 5 ans. Utilisez-le et FasterXML / jackson-modules-java8 .