2. Un premier exemple

2.1. Introduction

Nous allons ici construire un premier service REST simple, permettant de servir des documents XML représentant nos marins. On décide que l'URI de chaque marin doit avoir la forme suivante :
 http://www.paumard.org/marin/123
Dans cette chaîne de caractères, 123 représente l'ID du marin dont on veut la représentation XML. C'est donc une grandeur variable, dont dépendra le contenu servi.

2.2. Création d'un service REST sous Netbeans

Techniquement un service REST est une application web. Il nous faut donc créer un projet web sous Netbeans, comme indiqué sur la figure suivante.
Création d'un projet web sous Netbeans

Figure 1. Création d'un projet web sous Netbeans


Ensuite, Netbeans nous permet de créer directement une classe qui implémente un service REST. Même si cette classe elle-même est très simple à écrire, l'infrastructure technique que Netbeans créé également n'est pas négligeable. Pour cela, il faut créer un nouveau fichier, et choisir par exemple "RESTful webservice from pattern" dans l'onglet "Web Services" du créateur de fichier.
Création d'un service REST

Figure 2. Création d'un service REST


L'étape suivante consiste à choisir un pattern pour ce service. On sélectionne ici "Simple root resource".
Sélection du pattern Simple root resource

Figure 3. Sélection du pattern "Simple root resource"


Enfin la dernière étape nous demande de préciser la classe qui va porter ce service. De plus, on choisit "rs" comme chemin d'accès pour cette ressource. On laisse leurs valeurs par défaut aux autres paramètres.
Paramétrage final du service

Figure 4. Paramétrage final du service


Netbeans nous crée alors une classe, MarinService, qui porte ce service REST. Examinons cette classe.

Exemple 26. Un premier service REST : MarinService

@Path("rs")
 public  class MarinService {
     @Context
     private UriInfo context;

     @GET
     @Produces("application/xml")
     public String getXml() {
         // contenu de la méthode
    }
    
     @PUT
     @Consumes("application/xml")
     public  void putXml(String content) {
         // contenu de la méthode
    }
}

Remarquons les choses suivantes sur cette première classe.
  • Il s'agit d'une classe Java tout à fait standard : elle n'étend aucune classe particulière, et n'implémente aucune interface. Elle possède un constructeur vide, ici le constructeur vide par défaut. Le point important, est qu'elle est annotée par @Path("rs"). C'est la présence de cette annotation qui fait de cette classe un service REST.
  • Elle possède deux méthodes, peu importe leur nom, annotées par @GET et @PUT. Ces deux annotations correspondent à deux méthodes HTTP. Lors d'une requête de type get, c'est la méthode annotée @GET qui sera invoquée. Même chose pour une requête de type put : c'est la méthode annotée @PUT qui sera invoquée.
  • Enfin les deux annotations @Consume et @Produce précisent le format des données qui seront reçues ou émises par chacune de ces méthodes : ici du XML.
Un deuxième élément a été créé, qui se trouve dans le fichier web.xml de cette application web. Examinons les éléments que Netbeans a ajoutés pour nous.

Exemple 27. Fichier web.xml du service REST

<?xml version="1.0" encoding="UTF-8"?>

 <web-app  version="2.5" 
          xmlns="http://java.sun.com/xml/ns/javaee" 
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
          xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
                             http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

     <servlet>
         <servlet-name>ServletAdaptor</servlet-name>
         <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
         <load-on-startup>1</load-on-startup>
     </servlet>
    
     <servlet-mapping>
         <servlet-name>ServletAdaptor</servlet-name>
         <url-pattern>/resources/*</url-pattern>
     </servlet-mapping>
    
     <!-- reste du fichier web.xml -->
 </web-app>

On constate que Netbeans a créé une servlet, dont le nom est servlet ServletAdaptor, et la classe ServletContainer. Cette servlet traite toutes les requêtes qui arrivent sur toutes les URL commençant par /resources. Le fonctionnement d'un service REST apparaît ici. Techniquement, il s'agit d'une unique servlet classique, vivant dans une application web standard. Cette servlet connaît les classes possédant l'annotation @Path, et est capable de distribuer vers elles les requêtes qui les concernent. Nous reverrons ce point plus en détails dans la suite de ce chapitre.

2.3. Création d'un modèle

Notre service MarinService a besoin de servir des marins. Et ça tombe bien, nous en avons quelques-uns sous la main. Ajoutons une classe Marin à notre projet, avec des annotations JAXB.

Exemple 28. Classe Marin pour notre service REST

@XmlRootElement(name="marin", 
                namespace="http://cours.paumard.org/rest")
 public  class Marin {

     @XmlAttribute
     private  long id ;

     private String nom, prenom ;

     int age ;
    
     // suite de la classe
}

Cette classe est tout à fait standard par rapport à celles que nous avons créées dans la partie précédente.

2.4. Modification du service REST

Modifions à présent notre service REST pour la prendre en compte.

Exemple 29. Version modifiée sur service REST MarinService

@Path("marin/{id}")
 public  class MarinService {

     @GET
     @Produces("application/xml")
     public Object getMarin(@PathParam("id")  long id) {

        Marin marin =  new Marin() ;
        marin.setId(id) ;
        marin.setNom("Surcouf") ;
        marin.setPrenom("Robert") ;
        marin.setAge(32) ;
        
         return marin ;
    }
}

De la classe originale, nous n'avons pas gardé grand chose. Regardons les éléments que nous avons ajoutés.
  • Nous avons modifié la valeur de l'annotation @Path. Sa valeur est maintenant /main/{id}. La partie /{id} signifie qu'une URL de la forme /marin/15 sera acceptée, et qu'un paramètre de chemin id sera créé pour cette requête, de valeur 15.
  • Notre méthode @GET a changé de nom, ce qui n'a pas d'importance, vu que ce qui compte c'est son annotation et non pas son nom. En revanche, son type de retour est maintenant Object plutôt que String. Elle prend un paramètre, qui est annoté par @PathParam("id"). Cette annotation signifie que la valeur du paramètre de cette méthode correspondra à la valeur du paramètre de chemin id.
  • Enfin dans le corps de cette méthode, on crée un marin, en fixant la valeur de son id à la valeur passée en paramètre. Les autres champs sont classiques. On imagine qu'à terme, ce marin sera lu en base, soit directement, soit au travers d'un EJB session facade .
L'objet retourné par cette méthode est simplement marin. Le fait que cette méthode soit annotée par @Produces("application/xml"), et que notre classe Marin porte des annotations JAXB, va automatiquement déclencher le marshalling de cet objet en XML, par JAXB.

2.5. Invocation du service REST

Avant de pouvoir utiliser ce service, il nous faut encore modifier le fichier web.xml généré par Netbeans. Cette modification est mineure : il suffit de remplacer le contenu de l'élément url-pattern par /*. Lançons ce service, en utilisant l'option "Deploy" du menu contextuel dans Netbeans.
Lancement de notre premier service REST

Figure 5. Lancement de notre premier service REST


Enfin, pour l'utiliser, il suffit de faire une requête à l'aide d'un navigateur standard sur l'URL utilisée par Netbeans. Il s'agira d'une URL du type :
 :8008/cours-rest/marin/15
Cette URL est composée de trois éléments.
  • :8008 : correspond à l'URL sur laquelle le serveur utilisé par Netbeans est lancé (Glassfish ou Tomcat le plus souvent). Cette partie de l'URL est à adapter en fonction de la configuration locale.
  • /cours-rest : le point de montage utilisé par Netbeans pour déployer une application web correspond au nom du projet qui porte cette application. Cette URL doit donc aussi être adaptée en fonction de la configuration locale.
  • /marin/15 : cette dernière partie de l'URL permet de s'adresser à notre service web tel que nous l'avons défini.
On reçoit le document XML suivant en réponse à cette requête.

Exemple 30. Document XML servi

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

 <ns2:marin  xmlns:ns2="http://cours.paumard.org/rest"  id="15">
     <nom>Surcouf</nom>
     <prenom>Robert</prenom>
     <age>32</age>
 </ns2:marin>

On constate qu'il s'agit bien de notre marin, marshallé en XML par JAXB.
JAXB et services REST
Retour au blog Java le soir
Cours & Tutoriaux