J'ai une application simple avec Spring Boot et Jetty. J'ai un contrôleur simple qui retourne un objet qui a une Java 8 ZonedDateTime
:
public class Device {
// ...
private ZonedDateTime lastUpdated;
public Device(String id, ZonedDateTime lastUpdated, int course, double latitude, double longitude) {
// ...
this.lastUpdated = lastUpdated;
// ...
}
public ZonedDateTime getLastUpdated() {
return lastUpdated;
}
}
Dans ma RestController
j'ai simplement:
@RequestMapping("/devices/")
public @ResponseBody List<Device> index() {
List<Device> devices = new ArrayList<>();
devices.add(new Device("321421521", ZonedDateTime.now(), 0, 39.89011333, 24.438176666));
return devices;
}
Je m'attendais à ce que la ZonedDateTime
soit formatée conformément au format ISO, mais au lieu de cela, je reçois un dump JSON complet de la classe comme suit:
"lastUpdated":{"offset":{"totalSeconds":7200,"id":"+02:00","rules":{"fixedOffset":true,"transitionRules":[],"transitions":[]}},"zone":{"id":"Europe/Berlin","rules":{"fixedOffset":false,"transitionRules":[{"month":"MARCH","timeDefinition":"UTC","standardOffset":{"totalSeconds":3600,"id":"+01:00","rules":{"fixedOffset":true,"transitionRules":[],"transitions":[]}},"offsetBefore":{"totalSeconds":3600,"id":"+01:00","rules":{"fixedOffset":true,"transitionRules":[],"transitions":[]}},"offsetAfter":{"totalSeconds":7200,"id":"+02:00", ...
Je viens d'avoir une application spring-boot-starter-web
, en utilisant spring-boot-starter-jetty
et en excluant spring-boot-starter-Tomcat
.
Pourquoi Jackson se comporte-t-il de la sorte dans Spring Boot?
** METTRE À JOUR **
Pour ceux qui recherchent un guide complet étape par étape sur la façon de résoudre ce problème, j'ai trouvé ceci après avoir posé la question: http://lewandowski.io/2016/02/formatting-Java-time-spring- boot-using-json /
Il existe une bibliothèque jackson-datatype-jsr310 . Essayez-le.
Cette bibliothèque couvre la nouvelle API datetime et inclut des sérialiseurs pour ZonedDateTime
.
Tout ce dont vous avez besoin est simplement d’ajouter JavaTimeModule
:
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
METTRE &AGRAVE; JOUR
Pour convertir date/heure en ISO-8601
string, vous devez désactiver WRITE_DATES_AS_TIMESTAMPS
feature. Vous pouvez facilement le faire en remplaçant le bean ObjectMapper
ou en utilisant propriétés de l'application :
spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS = false
Si vous ne vous fiez pas à la fonctionnalité de configuration automatique de SpringBoot - vous ne fournissez pas la propriété spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS = false
dans votre fichier de configuration - ou pour une raison quelconque, vous créez manuellement une instance ObjectMapper
. Vous pouvez désactiver cette fonctionnalité par programme comme suit:
ObjectMapper m = new ObjectMapper();
m.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
ceci est pour jackson 2.8.7
La réponse a déjà été mentionnée ci-dessus, mais je pense qu'il manque des informations. Pour ceux qui cherchent à analyser les horodatages Java 8 sous de nombreuses formes (pas seulement ZonedDateTime). Vous avez besoin d'une version récente de jackson-datatype-jsr310
dans votre POM et le module suivant est enregistré:
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
Pour tester ce code
@Test
void testSeliarization() throws IOException {
String expectedJson = "{\"parseDate\":\"2018-12-04T18:47:38.927Z\"}";
MyPojo pojo = new MyPojo(ZonedDateTime.parse("2018-12-04T18:47:38.927Z"));
// serialization
assertThat(objectMapper.writeValueAsString(pojo)).isEqualTo(expectedJson);
// deserialization
assertThat(objectMapper.readValue(expectedJson, MyPojo.class)).isEqualTo(pojo);
}
Notez que vous pouvez configurer votre mappeur d’objets globalement dans Spring ou dans l’assistant dropwizard pour y parvenir. Je n'ai pas encore trouvé de moyen propre de le faire en tant qu'annotation sur un champ sans enregistrer un (dés) sérialiseur personnalisé.