Le titre est déjà tout un programme ! L'objectif est d'illustrer avec plusieurs exemples les nouveautés Rest API dans Spring MVC 4 et en particulier sur le support Jackson2 dans Spring4.
Nous allons voir de quelle manière nous pouvons ignorer certains attributs de classe, puis comment filtrer certains champs dans les conversions/sérialisations Json (ou encore Xml). Les conversions (sérialisation et désérialisation) des dates seront également traitées.
Le test unitaire JUnit à l'aide de RestTemplate permet de mettre en pratique toutes ces notions.
Le projet démo est basé sur spring-boot mais il n'est pas nécessaire pour comprendre ce billet.
1. Configurer le projet maven démo
Une seule dépendance est nécessaire puisque notre pom hérite de celui de spring-boot.
Or comme nous produisons des tests unitaires, on ajoute l'artifact "spring-boot-starter-test".
Ainsi le pom du projet contient ceci:
Notez que java 8 est utilisé, par conséquent il est important d'avoir installé jdk8 en amont.
2. Le use-case
Notre use case est simple mais réaliste. Il s'agit de répondre à une requête client : lister une ou plusieurs personnes répertoriée(s) dans notre base de données.
En fonction d'un critère (ou profil), on souhaite pouvoir afficher la totalité ou une partie des informations de ces personnes.
Ainsi si le client lance l'uri /personResume , nous lui retournerons du json , juste un résumé de l'identité de la personne (ici l'id & le nom seulement).
Par contre, la réponse json comporte l'id, le nom, la localisation et la date de naissance de la personne lorsque l'url est /personDetaille.
Mais alors comment faire? La suite de ce billet présente les étapes détaillées.
3. Le modèle
Écrivons notre classe modèle Person en tenant compte de notre cas d'utilisation. Pour l'instant Person est un POJO simple ayant ces attributs: id (int), name(String), locations(Lis<String>), dateNce(java.util.Date).
A l'étape suivante on va enrichir la classe Person avec des annotations sur ces attributs, ce qui nous permettra de les filtrer lors de la conversion java <=> JSON or XML.
4. Filtrer les conversions Jackson
Pour réaliser ces filtres, nous procéderons en deux temps :
Etape 1. Écrivons ces deux interfaces vides comme suit:
Etape2. Enrichir la classe Person avec des annotations du filtre Jackson2:
Explication: com.fasterxml.jackson.annotation.JsonView
est une annotation de jackson 2. Spring MVC offre désormais le support de Jackson’s Serialization Views.
5. Rest controller
Il est temps de construire le controller de notre webservice Rest pour répondre aux requêtes http des clients. Avant cela, ajoutons cette méthode simple du service :
La méthode getPersonDetail simule la récupération de données de notre BD. Voici le contenu du controller Rest qui ne fait qu'appeler le service:
Quelques points méritent que l'on apporte de petites précisions :
- La classe est annotée avec @RestController (@RestController combine @ResponseBody and @Controller, comme le dit la doc de réf de Spring),
- Deux méthodes du controller utilisant la même méthode du service: La première getPerson pour répondre à l'uri /personResume.json La seconde répond à /personDetaille.json,
- Enfin, la seule différence entre ces deux méthodes correspond aux deux annotations laissées pour l'instant en commentaire:
@JsonView(Views.Resume.class)
et @JsonView(Views.Detaille.class)Il est donc indispensable de dé-commenter ces deux lignes pour activer les filtres de sérialisation/désérialisation définis dans le modèle à l'étape2.
NOTE. Il est indispensable d'appliquer l'annotation @JsonView ( Views.xxxxx.class) aux méthodes getPersonXXXX du controller afin d'activer ces filtres.
Par exemple, appliquer l'annotation @JsonView (Views.Detaille.class) à la méthode getPersonDetail fournit un json avec l'ensemble des attributs de Person.
6. Tester le RestController
Le test JUnit permet de valider les méthodes de notre webservice Rest. Là encore Spring rend les choses faciles encore plus simples.
En effet, une classe JUnit saupoudrée avec quelques annotations de Spring et puis RestTemplate fait presque tout. Voici donc le code du test unitaire JUnit 4:
Attention dans ce test il y a des adaptations à faire :
- Il manque la classe AppConfig permettant de configurer Spring4, voir ci-dessous.
- La constante BASE_URL doit être adaptée selon votre web contexte (context path).
Notez l'assertion sur p.getLocations() à null dans la méthode testGetPersonResume
.
Ceci confirme que le filtre @JsonView (Views.Resume.class) ne retourne pas les locations de Person comme sera illustré ci-après. Et comme indiqué, voici le code de la classe AppConfig ainsi que l'initialisation par java du projet web puisqu'on utilise pas web.xml.
Pensez à adapter l'argument de @ComponentScan avec le nom de votre package. Et pour finir la classe WebApplicationInitializer nécessaire à l'initialisation du projet web (lorsqu'on utilise pas entièrement spring-boot).
7. Exécuter le test
Avant de lancer le test, assurez-vous que votre projet web est lancé sur un serveur web (tomcat ou autre) et est en écoute sur le port (par défaut) 8080.
La première capture illustre l'appel à /personResume qui retourne uniquement l'id et le nom.
Alors que getPersonDetaille retourne la liste des locations comme le montre la capture ci-dessous :
Ooups! La date de naissance (dateNce) est mal affichée. C'est illisible !
La seconde partie de ce billet tente de remédier à cela.
Mais avant, attendez un peu!
Où déclare t-on la conversion de Jackson2 ?
Spring et RestTemplate viennent avec une liste de "MessageConverters" configurée par défaut. En fonction du type de média (content-type défini dans le header de la requête) le bon converter est fixé automatiquement.
Par exemple, lorsque le type média est "application/json" la réponse (au format json) est fournie avec le converter nommé "MappingJacksonHttpMessageConverter".
A l'aide du plugin "Advanced Rest Client", vous pouvez tester Rest et voir le type média (sur la capture application/json).
A bientôt!
Il existe aussi PostMan, je le trouve cool pour tester les app RESTful
https://www.getpostman.com/