J'utilise la bibliothèque décrite la page Jackson Datatype JSR310 mais j'ai toujours du mal à la faire fonctionner.
J'ai configuré le haricot suivant:
@Bean
@Primary
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JSR310Module());
return mapper;
}
Lorsque j'appelle mon API REST, le format de date généré est yyyy-MM-dd'T'HH:ss.SSSSSS
, par exemple. 2015-04-11T00:10:38.905847
. Ceci est parfaitement géré par mon code AngularJS.
Lorsque je souhaite soumettre quelque chose à l'API REST, la date est publiée sous la forme yyyy-MM-dd'T'HH:mm:ss.SSS'Z'
, par exemple. 2015-04-09T08:30:00.000Z
Jackson continue à se plaindre du "Z" à la fin. Si je regarde la LocalDateTimeDeserializer
dans la documentation, il utilise le DateTimeFormatter.ISO_LOCAL_DATE_TIME
qui se résume en ISO_LOCAL_DATE'T'ISO_LOCAL_TIME
et il mentionne qu'il n'a pas de zone de substitution.
J'ai donc pensé que je devrais définir la DateFormat
sur la ObjectMapper
que je crée:
@Bean
@Primary
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JSR310Module());
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"));
return mapper;
}
Mais cela ne fait rien. Je l'ai changé pour quelque chose de simple comme yyyy-MM-dd
mais la date sérialisée est restée dans le format précédent et la désérialisation n'est pas affectée non plus.
Qu'est-ce que je fais mal ici pour que cela fonctionne? Le format de date dans mon code JavaScript est, à ma connaissance, le format ISO 8601 ...
Il n'est pas nécessaire d'écrire votre propre sérialiseur. Il suffit d’utiliser celui par défaut, mais en créant une instance avec un autre format (le time_zone
) pour que la partie en excès soit simplement coupée:
new LocalDateTimeDeserializer(DateTimeFormatter.ISO_DATE_TIME)
Dans mon cas, j'ai une contextResolver
comme celle-ci à réaliser au niveau de la configuration:
@Service
@Provider
public class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> {
private final ObjectMapper mapper;
public ObjectMapperContextResolver() {
mapper = new ObjectMapper();
JavaTimeModule javaTimeModule=new JavaTimeModule();
// Hack time module to allow 'Z' at the end of string (i.e. javascript json's)
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ISO_DATE_TIME));
mapper.registerModule(javaTimeModule);
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
}
@Override
public ObjectMapper getContext(Class<?> type) {
return mapper;
}
}
Pour l'instant, LocalDateTimeDeserializer
ne semble pas respecter le format de date défini pour le mappeur d'objets.
Pour que cela fonctionne, vous pouvez remplacer LocalDateTimeDeserializer
ou utiliser ZoneDateTime
qui gère le caractère 'Z' à la fin.
Voici un exemple:
public class Java8DateFormat {
public static void main(String[] args) throws IOException {
final ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JSR310Module());
// mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"));
final String date = mapper.writeValueAsString(new Date());
System.out.println(date);
System.out.println(mapper.readValue(date, ZonedDateTime.class));
}
}
Sortie:
"2015-04-11T18:24:47.815Z"
2015-04-11T18:24:47.815Z[GMT]
Hibernate 4, Spring 4 - REST WS, Client - Spring Boot 1.5.2. Dans mon cas, j'ai utilisé dans la classe Entity ZonedDateTime pour mapper Timestamp dans la base de données. Hibernate et Spring Boot REST fonctionnent correctement. Je dois seulement ajouter des bibliothèques dans le fichier pom:
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.datatype/jackson-datatype-jsr310 -->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
</dependency>
Donc, je suppose que ce convertisseur est également implémenté dans Spring pour LocalDateTime. Le jackson.version est le dernier.