Fred Talks

Des petites solutions pour des petits problèmes…

Rest Web Service Get avec Spring

27 Jan 2015

La mise en œuvre d'un web service REST peut être facilement réalisée en utilisant la librairie Spring 4 via les annotations en basant sur la norme Servlet 3.0.

Pour mieux appréhender le protocole REST, il est vivement conseillé de lire la page suivante : http://www.restapitutorial.com/lessons/restquicktips.html

Près-requis

Vous avez une environnement Eclipse fonctionnel avec à minima un jdk 1.6 et un tomcat 7.0.

Préparation du projet

Pour commencer, je vous invite à récupérer le squelette du projet sur mon github dans un répertoire projet via les commandes :

git clone https://github.com/draoullig/SpringRestWS.git

cd SpringRestWS

git checkout step0

mkdir src

Importer le projet sous Eclipse via File>Import>General>Existing Projects into Workspace et sélectionner SpringRestWS dans le répertoire dans lequel vous avez réalisé le git clone, puis finissez l'import.

Dans la vue "Java EE - Eclipse", ajouter le package fr.gillouard.spring.restws via un click droit sur src>New>Package et valider.

Les librairies nécessaires au projet sont présentes dans le répertoire /web/WEB-INF/lib.

Pojo

Les classes Pojo vont permettre de gérer le modèle associé au web service.
Ce tutorial s'appuie sur un modèle simple constitué d'une seul objet client caractérisé par un identifiant, un nom et un prénom.

Package

Création d'un nouveau package pojo sous le package fr.gillouard.spring.restws.
Pour cela faire un clic droit sur le package fr.gillouard.spring.restws et cliquer sur New/Package.
Ajouter .pojo à fr.gillouard.spring.restws dans le champs Name de la boite de dialogue New Java Package et cliquer sur Finish.

Client

Création d'une nouvelle classe dans le package fr.gillouard.spring.restws.pojo. Pour cela faire un clic droit sur le package et cliquer sur New/Class.
Saisir Client dans le champs Name de la boite de dialogue New Java Class puis cliquer sur Finish.
Ouvrir le fichier Client.java en double cliquant dessus.

Ajouter le code suivant au corps de la classe Client et enregistrer :

/**
  * Identifiant du client.
  */
private String identifiant;

/**
  * Nom du client.
  */
private String nom;

/**
  * Prénom du client.
  */
private String prenom;

/**
  * Constructeur.
  *
  * @param identifiant du client
  * @param nom du client
  * @param prenom du client
  */
public Client(final String identifiant, final String nom, final String prenom) {
 this.identifiant = identifiant;
 this.nom = nom;
 this.prenom = prenom;
}

/**
  * @return the identifiant
  */
public String getIdentifiant() {
 return identifiant;
}

/**
  * @param identifiant the identifiant to set
  */
public void setIdentifiant(final String identifiant) {
 this.identifiant = identifiant;
}

/**
  * @return the nom
  */
public String getNom() {
 return nom;
}

/**
  * @param nom the nom to set
  */
public void setNom(final String nom) {
 this.nom = nom;
}

/**
  * @return the prenom
  */
public String getPrenom() {
 return prenom;
}

/**
  * @param prenom the prenom to set
  */
public void setPrenom(final String prenom) {
 this.prenom = prenom;
}

Cette classe Client regroupe les champs identifiant, nom et prenom avec les accesseurs get et set sur chaque champs et un constructeur pour la création de l'objet.

Contrôleur

Les classes contrôleur vont permettre d'exposer le web service en REST à partir des annotations Spring.

Package

Création d'un nouveau package controller sous le package fr.gillouard.spring.restws.
Pour cela faire un clic droit sur le package fr.gillouard.spring.restws.pojo et cliquer sur New/Package.
Remplacer pojo par controller dans le champs Name de la boite de dialogue New Java Package et cliquer sur Finish.

Client Contrôleur

Cette classe va permettre de récupérer les clients via un appel REST de type GET.

Création d'une nouvelle classe dans le package fr.gillouard.spring.restws.controller. Pour cela faire un clic droit sur le package et cliquer sur New/Class.
Saisir ClientControleur dans le champs Name de la boite de dialogue New Java Class puis cliquer sur Finish.
Ouvrir le fichier ClientControleur.java en double cliquant dessus.

Ajouter les imports suivants :

import java.util.ArrayList;
import java.util.List;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import fr.gillouard.spring.restws.pojo.Client;

Ajouter les annotations suivantes à la classe :

@RestController
@RequestMapping("/client")

Ajouter le code suivant dans le corps de la classe et sauvegarder :

 /**
  * Liste des clients
  */
private final List<Client> clients = new ArrayList<Client>();

/**
  * Lister l'ensemble des clients
  *
  * @return la liste complete des clients
  */
@RequestMapping(method = RequestMethod.GET)
public List<Client> getClients() {
 return clients;
}

L'annotation @RestController permet d'indiquer que cette classe est un contrôleur qui utilise des flux json pour faire du REST.
L'annotation @RequestMapping permet d'indiquer le mapping d'url pour lequel le contrôleur doit répondre, dans ce cas-ci il s'agit de l'url /client.

La liste des clients est géré simplement via une ArrayList dans le cas de ce tutorial.
La fonction getClients est annotée via @RequestMapping pour indiquer que le mapping est réalisé sur l'url /client sur une requête http de format GET.
Cette fonction retourne tous les clients de la liste.

Spring java configuration

Désormais Spring permet de réaliser toute sa configuration sans utiliser un ligne de xml. Dans cette section, la configuration du service web REST va être décrite.

Package

Création d'un nouveau package config sous le package fr.gillouard.spring.restws.
Pour cela faire un clic droit sur le package fr.gillouard.spring.restws.pojo et cliquer sur New/Package.
Remplacer pojo par config dans le champs Name de la boite de dialogue New Java Package et cliquer sur Finish.

SpringConfig

Cette classe permet de créer l'injection du contexte Spring du projet.

Assurez vous que les librairies de votre serveur d’exécution (Ici Tomcat 7.0 à minima) soient bien dans le classpath du projet.

Création d'une nouvelle classe dans le package fr.gillouard.spring.restws.config. Pour cela faire un clic droit sur le package et cliquer sur New/Class.
Saisir SpringConfig dans le champs Name de la boite de dialogue New Java Class puis cliquer sur Finish.
Ouvrir le fichier SpringConfig.java en double cliquant dessus.

Ajouter les imports suivants :

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

Ajouter les annotations suivantes à la classe :

@Configuration
@ComponentScan("fr.gillouard.spring.restws")

Faire hériter la classe de WebMvcConfigurationSupport via :

extends WebMvcConfigurationSupport

Ajouter le code suivant dans le corps de la classe :

 /**
  * Constructeur.
  */
 SpringConfig() {
 super();
}

L'annotation @Configuration permet de préciser que cette classe réalise le chargement du contexte Spring et le met à disposition.
L'annotation @ComponentScan("fr.gillouard.spring.restws") permet d'indiquer que la création du contexte est réalisé en scannant tous les classes de la hiérarchie de package précisé. Ainsi les annotations de la classe ClientController sont analysées et traitées.
La classe de configuration ne contient qu'un constructeur parce que tout le traitement est effectué par les annotations.

WebAppInitializer

Cette classe va être instanciée au démarrage du conteneur (Norme Servlet 3) et charge la configuration du contexte pour le serveur d'exécution.

Création d'une nouvelle classe dans le package fr.gillouard.spring.restws.config. Pour cela faire un clic droit sur le package et cliquer sur New/Class.
Saisir WebAppInitializer dans le champs Name de la boite de dialogue New Java Class puis cliquer sur Finish.
Ouvrir le fichier WebAppInitializer.java en double cliquant dessus.

Ajouter les imports suivants :

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration.Dynamic;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

Implémenter la classe de WebApplicationInitializer via :

implements WebApplicationInitializer

Ajouter le code suivant dans le corps de la classe et sauvegarder :

/**
  * Methode appelee au demarrage du serveur
  *
  * @param servletContext
  *            contexte de demarrage du serveur
  */
@Override
public void onStartup(final ServletContext servletContext)
  throws ServletException {

 // Creation de la configuration Spring
 final AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
  context.register(SpringConfig.class);
  context.setServletContext(servletContext);

 // Mise a disposition du contexte Spring
 servletContext.addListener(new ContextLoaderListener(context));
  servletContext.setInitParameter("defaultHtmlEscape", "true");

 // Filtrage des requetes via Spring
 final Dynamic dynamic = servletContext.addServlet("dispatcher",
   new DispatcherServlet(context));
  dynamic.addMapping("/");
  dynamic.setLoadOnStartup(1);

}

La classe implémente la méthode onStartup définit de la norme Servlet 3 et qui est exécutée au démarrage du serveur.
La méthode crée le contexte Spring en utilisant les annotations via la classe AnnotationConfigWebApplicationContext et en chargeant la classe SpringConfig.
Le contexte Spring est mis à disposition du serveur d'exécution et toutes les requêtes entrantes sur le serveur sont traités via les mécanismes Spring.

Runtime

Pour tester le web service, il est nécessaire de déployer le projet SpringRestWS sous un Tomcat v7.0.
Pour cela dans la vue Server, effectuer un clic droit sur le serveur cible et cliquer sur Add and Remove.
Dans la boite de dialogue Add and Remove, pousser le projet SpringRestWS dans la partie Configured et cliquer sur Finish.
Dans la vue Server, effectuer à nouveau un clic droit sur le serveur cible et cliquer sur Debug.

La vue Console devrait ressembler à ceci :

janv. 22, 2015 11:02:16 AM org.apache.catalina.core.ApplicationContext log
INFOS: Spring WebApplicationInitializers detected on classpath: [fr.gillouard.spring.restws.config.WebAppInitializer@33fdf5ca]
janv. 22, 2015 11:02:16 AM org.apache.catalina.core.ApplicationContext log
INFOS: Initializing Spring root WebApplicationContext
janv. 22, 2015 11:02:16 AM org.springframework.web.context.ContextLoader initWebApplicationContext
INFOS: Root WebApplicationContext: initialization started
janv. 22, 2015 11:02:16 AM org.springframework.web.context.support.AnnotationConfigWebApplicationContext prepareRefresh
INFOS: Refreshing Root WebApplicationContext: startup date [Thu Jan 22 11:02:16 CET 2015]; root of context hierarchy
janv. 22, 2015 11:02:16 AM org.springframework.web.context.support.AnnotationConfigWebApplicationContext loadBeanDefinitions
INFOS: Registering annotated classes: [class fr.gillouard.spring.restws.config.SpringConfig]
janv. 22, 2015 11:02:16 AM org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping registerHandlerMethod
INFOS: Mapped "{[/client],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.util.List<fr.gillouard.spring.restws.pojo.Client> fr.gillouard.spring.restws.controller.ClientControleur.getClients()
janv. 22, 2015 11:02:17 AM org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter initControllerAdviceCache
INFOS: Looking for @ControllerAdvice: Root WebApplicationContext: startup date [Thu Jan 22 11:02:16 CET 2015]; root of context hierarchy
janv. 22, 2015 11:02:17 AM org.springframework.web.context.ContextLoader initWebApplicationContext
INFOS: Root WebApplicationContext: initialization completed in 955 ms

Pour tester le web service, ouvrer un navigateur et saisir l'url suivante : http://localhost:8080/SpringRestWS/client en changeant le port en fonction de la configuration de votre serveur Tomcat.

Vous devriez obtenir ceci :

appel_web_service_1

La liste des clients est vide côté service, ce qui explique ce résultat.

Dans la vue Server, effectuer à nouveau un clic droit sur le serveur cible et cliquer sur Stop.

Data

Nous allons ajoutons des clients au service pour obtenir un résultat plus concluant.

Pour cela, ouvrir le fichier ClientControleur.java en double cliquant dessus.

Ajouter le code suivant dans le corps de la classe sous la ligne private final List<Client> clients = new ArrayList<Client>(); :

/**
 * Constructeur.
 */
public ClientControleur() {
 clients.add(new Client("1", "Dupont", "Jules"));
 clients.add(new Client("2", "Martin", "Anne"));
 clients.add(new Client("3", "Le Gall", "Bruno"));
}

Ce code ajoute un constructeur a la classe dans lequel on ajoute des clients à la liste.

Dans la vue Server, effectuer à nouveau un clic droit sur le serveur cible et cliquer sur Debug.

Effectuer un rafraîchissement dans votre navigateur sur la page précédente et vous devriez obtenir ceci :

Dans la vue Server, effectuer à nouveau un clic droit sur le serveur cible et cliquer sur Stop.

Conclusion

Ce tutorial a permis d'expliquer la mise en œuvre d'un web service REST en utilisant Spring uniquement sur la commande GET.

Solution

L'ensemble des sources de ce tutorial est disponible sous le tag step1.