J'essaie de désérialiser une date au format ISO8601 dans Java8 Instant à l'aide de Jackson. J'ai enregistré JavaTimeModule avec ObjectMapper, désactivé WRITE_DATES_AS_TIMESTAMPS.
Cependant, si on essaie de désérialiser le 2016-03-28T19: 00: 00.000 + 01: 00, cela ne fonctionnera pas, car il semblerait que JavaTimeModule ne désérialise que les dates date formatées avec le décalage du fuseau horaire UTC (par exemple, : 00.000Z). J'ai ensuite essayé d'utiliser l'annotation @JsonFormat comme ceci:
@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss.SSSZ", timezone = "UTC")
Et comme ça:
@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss.SSSZ", timezone = JsonFormat.DEFAULT_TIMEZONE)
Cependant, ni l'un ni l'autre ne fonctionne et je reçois une exception:
com.fasterxml.jackson.databind.JsonMappingException: Unsupported field: YearOfEra (through reference chain: org.example.Article["date"])
Ce qui implique que le paramètre fuseau horaire est ignoré et que le formateur de date/heure ne sait pas comment formater un instantané sans fuseau horaire.
Existe-t-il un moyen de désérialiser une chaîne ISO8601 qui n'est pas dans le fuseau horaire UTC décalé vers Java 8 Instant à l'aide de Jackson et de JavaTimeModule sans écrire de désérialiseur personnalisé?
Vous devez définir le fuseau horaire explicite via XXX
dans votre classe de modèle:
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
private Date date;
(voir: https://docs.Oracle.com/javase/7/docs/api/Java/text/SimpleDateFormat.html )
Le format "Z" ne fonctionne pas avec "+01: 00" car il s'agit d'un modèle différent . JsonFormat utilise des modèles SimpleDateFormat. "Z" dans les majuscules ne représentent que la RFC 822 stricte. Vous devez utiliser une syntaxe telle que: "+0100", sans les deux points.
Dans Jackson 2.9.8 (la version actuelle est celle où j'écris ceci), il est préférable d'utiliser Instant au lieu de Date.
Vous devez ajouter une dépendance:
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.9.8</version>
</dependency>
Enregistrez également le module et configurez SerializationFeature.WRITE_DATES_AS_TIMESTAMPS sur false.
new ObjectMapper()
.findAndRegisterModules()
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
Plus d'informations sur Jackson for Java8 ici: https://github.com/FasterXML/jackson-modules-Java8
Si vous souhaitez sérialiser des objets Date
dans ISO-8601, vous n'avez pas du tout besoin de spécifier un modèle - ISO-8601 est le modèle par défaut. Il est en quelque sorte mentionné dans le JsonFormat
Java doc :
Les utilisations courantes incluent le choix entre des représentations alternatives - par exemple, si Date doit être sérialisé en tant que nombre (horodatage Java) ou String (telle qu'une valeur de temps compatible ISO-8601) -, ainsi que la configuration des détails exacts avec un motif () propriété.
Vous devez comprendre d'après le texte ci-dessus que spécifier shape = STRING
signifierait un format ISO-8601 mais que vous pouvez choisir autre chose à l'aide de la propriété pattern
.
D'après mon expérience, cela donne toujours un format de date UTC (avec le fuseau horaire affiché en tant que +0000
), qui peut être le fuseau horaire par défaut de mon VM (même si l'horloge de mon système d'exploitation n'est pas définie sur UTC).