Problèmes avec Spring Boot lors de la sérialisation de java.time.LocalDateTime avec Jackson pour renvoyer les horodatages JSON ISO-8601?
Je suis en train de travailler sur la conversion de certains modèles, au printemps de démarrage RESTE de l'API de l'application à utiliser java 8 java.time.LocalDateTime
au lieu de joda est DateTime
. Je veux les horodateurs retourné à partir de l'API appel à adhérer à la ISO_8601
format. La Motivation est d'être compatible avec Java 8 (plus ici).
La partie qui s'avère difficile, c'est quand il s'agit de sérialiser un objet contenant LocalDateTime
en JSON.
Par exemple, j'ai l'entité suivante:
//... misc imports
import java.time.LocalDateTime;
import java.time.ZoneOffset;
@Data
@Entity
@Table(name = "users")
public class User {
@Id @Column
private String id;
@Column
private String name;
@Column
private String email;
@Column
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss", timezone = "UTC")
private java.time.LocalDateTime createdAt;
public User(String name, String email) {
this.id = Utils.generateUUID();
this.createdAt = LocalDateTime.now(ZoneOffset.UTC);
}
}
J'ai aussi mis mon application.properties
pour désactiver les dates sous forme de timestamp jackson fonctionnalité:
spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS = false
Mon maven deps:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.3.6.RELEASE</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.0.1.Final</version>
</dependency>
Enfin, j'essaie de récupérer la représentation JSON via le contrôleur:
@RequestMapping("/users")
@RestController
public class UserController {
private UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
@RequestMapping(
value = "/{id}",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_UTF8_VALUE
)
public User getUser(@PathVariable("id") String id) {
return userService.findById(id);
}
}
Lorsque j'ai fait faire un appel à ce point de terminaison, j'obtiens l'exception suivante:
java.lang.NoSuchMethodError:
com.fasterxml.jackson.datatype.jsr310.ser.JSR310FormattedSerializerBase.findFormatOverrides(Lcom/fasterxml/jackson/databind/SerializerProvider;Lcom/fasterxml/jackson/databind/BeanProperty;Ljava/lang/Class;)Lcom/fasterxml/jackson/annotation/JsonFormat$Value;
En alternance j'ai aussi configuré l'application ObjectMapper
dans la classe de configuration:
@Configuration
public class ServiceConfiguration {
@Bean
public ObjectMapper getJacksonObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
objectMapper.configure(
com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,
false
);
return objectMapper;
}
}
Tous les fils seront grandement appréciés.
Mise à JOUR:
S'avère que c'était une incompatibilité de version entre le Printemps bottes Jackson version et celle que j'avais dans mon pom.xml
. Comme Miloš et Andy proposé, une fois que j'ai mis la version correcte et exécuter l'application avec le spring.jackson.serialization.write_dates_as_timestamps=true
le problème a été résolu, sans avoir besoin de configurer le ObjectMapper
ou en ajoutant des annotations sur mon LocalDateTime
modèle de champs.
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.3.6.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.3.6.RELEASE</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
</dependencies>
source d'informationauteur sa125 | 2016-07-28
Vous devez vous connecter pour publier un commentaire.
La
NoSuchMethodError
est parce que vous êtes mélange de versions de Jackson. Printemps de Démarrage 1.3.6 utilise Jackson 2.6.7 et que vous utilisez 2.8.1 dejackson-datatype-jsr310
.Printemps de Démarrage fournit de gestion de la dépendance pour Jackson, y compris
jackson-datatype-jsr310
de sorte que vous devez supprimer la version de votre pom. Si vous souhaitez utiliser une autre version de Jackson, vous devez remplacer lejackson.version
propriété:Cela permettra d'assurer que tous vos Jackson dépendances ont la même version, et éviter d'éventuels problèmes avec les versions incohérentes.
Vous pouvez également, si vous le souhaitez, retirer votre code Java qui est de la configuration de la
ObjectMapper
. La Java module sera automatiquement enregistré dans le chemin de la classe et de l'écriture des dates que l'horodatage peut être configuré dansapplication.properties
:Votre
ObjectMapper
bean doit être marquée comme@Primary
pour être ramassé par un Ressort. Alternativement, vous pouvez simplement créer unJavaTimeModule
bean et il aura ramassé par le Printemps et ajouté à l'objet par défaut mappeur.Vous avez probablement déjà vu, mais jetez un oeil à la documentation officielle.