RESTer simple avec Spring et JAXB – Partie 2 : serveur REST avec Spring web

Ce billet fait suite au sujet portant sur le "Binding avec JAXB".
Après avoir réaliser le binding du modèle métier grâce aux annotations JAXB, la partie serveur de l'application peut être réalisée.
La façon la plus simple de réaliser une communication entre applications est de passer par des standards.
Le style d'architecte REST (Representational State Transfer) utilise des standards qui ont fait la renommée du web :

  • HTTP comme protocole de communication,
  • URI comme syntaxe d'adressage des ressources,
  • XML, Json... comme syntaxe pour la représentation des données.

Les avantages à utiliser REST sont multiples :

  • il ne dépend pas d'un langage,
  • taper une url dans un navigateur permet d'avoir un accès direct aux données,
  • de nombreux frameworks l'utilisent ce qui donne au développeur le choix de l'implémentation à utiliser.

Quels sont les possibilités pour faire du REST en java ?

  • Utiliser un des frameworks implémentant JAXRS, la spécification JAVA REST (Jersey, RESTEasy, CXF...),
  • Utiliser tout simplement un framework MVC couplé à un marshaller JAXB, ce que fait très bien Spring Mvc.

L'application de ce tutorial utilise la deuxième solution qui a le mérite d'être très simple et de nous permettre de rester dans l'écosystème Spring.

Pour faire dialoguer deux programmes, il faut spécifier tout d'abord le contrat d'utilisation du service à publier.
L'exemple est simple, il ne définit qu'un accès à une ressource "Client" par sa référence.

RestSimpleService.java :

public interface RestSimpleService
{
    Client getClient(final String reference);
}

Cette interface est placée dans le module API du projet, elle est partagée par le client et le serveur.

L'implémentation serveur de cette interface est écrite dans le module restsimple-serveur :

RestSimpleServiceImpl.java :

public class RestSimpleServiceImpl implements RestSimpleService
{
    
    public Client getClient(final String reference)
    {
        final Client client = new ClientImpl();
        
        client.setReference(reference);
        client.setNom("Nom");
        client.setPrenom("Prénom");
        client.setSociete("Société");
        client.setDateCreation(new LocalDate());
        
        
        final AdresseEmail adresse = new AdresseEmailImpl();
        adresse.setAdresse("nom@societe.com");
        adresse.setType(TypeAdresseEmail.PROFESSIONNEL);
        
        final List<AdresseEmail> adresses = new ArrayList<AdresseEmail>();
        adresses.add(adresse);
        client.setAdresseEmails(adresses);
        
        return client;
    }
    
}

Cette implémentation n'est qu'un stub, répondant la même chose à chaque appel. L'accès à une base de données n'est pas traité dans ce billet.

Voici la partie qui va permettre de rendre accessible cette méthode par le web. Un contrôleur Spring est utilisé. Il implémente la même interface et délègue l'accès aux données à l'implémentation vue ci-dessus.

RestSimpleControleur.java :

@Controller
public class RestSimpleControleur
    implements RestSimpleService
{

    private RestSimpleService service = null;

    @ResponseBody
    @RequestMapping(value = "/client/{reference}", method = RequestMethod.GET)
    public Client getClient(@PathVariable final String reference)
    {
        return getService().getClient(reference);
    }

    protected RestSimpleService getService()
    {
        return this.service;
    }

    public void setService(final RestSimpleService service)
    {
        this.service = service;
    }

}

Dans cette classe, différents points sont à aborder :

  • @Controller : Spring prend en compte cette classe dans sa servlet Dispatcher
  • @RequestMapping : cette annotation définit le chemin d'accès à la méthode et le type d'appel (GET).
  • @PathVariable : ce paramètre est récupéré de la requête GET.
  • Le service délégué est injecté par spring d'où l'accesseur en écriture public "setService"

Du côté du contexte spring
Voici les beans définis pour la mise en œuvre du contrôleur.

Déclaration du service dans le contexte de l'application

<bean id="restSimple.service" class="com.netapsys.restsimple.service.impl.RestSimpleServiceImpl"/>

Déclaration du contrôleur dans le contexte lié à la servlet Dispatcher

<bean id="restSimple.controller" class="com.netapsys.restsimple.controleur.RestSimpleControleur">
	<property name="service" ref="restSimple.service"/>
</bean>

Si nous nous arrêtons là, la dispatcher servlet ne pourra pas interpréter le résultat de la méthode getClient du contrôleur.
En effet, comment peut elle afficher un objet Client dans une page web ?
Nous définissons donc un adaptateur permettant de convertir l'objet en xml.

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
	<property name="messageConverters">
		<list>
			<bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"/>
			<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
			<bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
			<bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"/>
			<bean class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter"/>
		</list>
	</property>
</bean>, spring, 

Cet adaptateur possède une liste de messageConverters permettant de convertir les entrées/sorties des méthodes du contrôleur.
Ici, L'AnnotationMethodHandlerAdapter est construit par défaut avec des convertisseurs de String, de tableaux d'octets...
Un convertisseur d'annotation JAXB lui est ajouté pour pouvoir convertir l'objet Client en xml.

Nous ne détaillerons pas la configuration du web.xml de l'application, je vous laisse regarder les sources jointes au billet.

C'est tout pour le partie serveur !!

Après lancement du serveur web (mvn tomcat:run pour les utilisateurs de maven), le test d'accès aux données se fait par un navigateur avec le lien suivant :

http://localhost:8080/restsimple-serveur/client/005

L'utilisation de spring-mvc comme framework REST possède des inconvénients. A l'inverse d'un framework dédié comme RESTeasy ou CXF, il ne déploie pas de wsdl. Ceci est un gros problème lorsque des clients utilisent des générateurs de code basés sur ce fichier de définition. Une autre inconvénient provient du fait que cet exemple ne suit pas la spécification JAXRS. Un changement d'implémentation (ici spring-mvc) nécessite un changement de contrôleur.

La dernière partie de ce projet va nous emmener vers l'utilisation cliente de REST grâce aux RestTemplate spring.

Un commentaire

  1. j ai un projet à faire cette année j ss un deboutant en informatique le theme de mon projet est: »gestion de répartition des salles sous j2ee connecté à mysql,java ».Moi personnellement j aime faire de projet,je n arrive pas mai j vs demend de m aider puuis des cour complet sur j2ee

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Captcha *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.