Service Web REST en Java

L’objet de cette page est de présenter les service Web REST par la pratique en Java. L’idée générale est d’offrir un accès à des ressources via une interface commun construite au dessus de http : le serveur est un serveur web et un appel de méthode est un accès à une URL. Les opérations ne sont pas simplement des GET mais classiquement :

  • GET : Accès à une ressource
  • POST : création d’une ressource
  • DELETE : suppression d’une ressource
  • PUT : mise à jour ou création d’une ressource.

Attention lire la RFC 2616 (HTTP methods) en particulier pour les nuances entre PUT et POST. https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

Le format des données échangées est habituellement du texte, du XML et du JSON.

L’archetype maven suivant permet de créer un projet de base :

mvn archetype:generate \
  -DarchetypeGroupId=org.glassfish.jersey.archetypes \
  -DarchetypeArtifactId=jersey-quickstart-grizzly2 \
  -DarchetypeVersion=3.0.0

Lorsque l’application est exécutée un serveur web est lancé et la ressource est accessible :

mvn package && mvn exec:java

Il est possible d’accéder à la ressource en ligne de commande. Regarder les options de la commande curl pour réaliser des requêtes HTTP. Des extensions pour les navigateurs web existent aussi comme postman pour chrome.

curl -v --get http://localhost:8080/myapp/myresource

La définition des méthodes accessibles est donnée dans un document xml généré automatiquement. Attention, les dépendances nécessaires pour cela ne sont plus dans les JDK post version 8. Il faudra ajouter des dépendances (cf. demo plus complète en fin de cours).

curl -v --get http://localhost:8080/myapp/application.wadl

Dans le pom.xml décommenter la dépendance pour JSON si besoin.

La classe MyResource présente le fonctionnement basique. La classe est annotée avec @Path(your_path) pour indiquer le chemin de base dans l’URL correspondant à cette ressource.

Les méthodes sont annotées avec @POST, @GET, @PUT, @DELETE pour indiquer le type de méthode http associée. Les méthodes associées à GET sont aussi annotées avec @Produces qui indique le type mime dans lequel le résultat doit être fourni : @Produces(“text/plain”), @Produces(“application/json”), … Il possible d’indiquer plusieurs types : @Produces({“application/json”, “application/xml”}).

Les méthodes qui nécessite des paramètres sont annotées avec @Consumes(type[, type, …]) pour indiquer les types mime supportés. L’annotation @PathParam permet d’injecter les valeurs provenant des URL comme des paramètres.

Le projet dans l’entrepôt git suivant donne un exemple un peu plus complet :

# ajouter l’entrepôt maven bintray à votre ~/.m2/settings.xml
<settings>
  <profiles>
       <profile>
           <repositories>
               <repository>
                   <snapshots>
                       <enabled>false</enabled>
                   </snapshots>
                   <id>bintray-dptinfoutln-public</id>
                   <name>bintray</name>
                   <url>https://dl.bintray.com/dptinfoutln/public</url>
               </repository>
           </repositories>
           <pluginRepositories>
               <pluginRepository>
                   <snapshots>
                       <enabled>false</enabled>
                   </snapshots>
                   <id>bintray-dptinfoutln-public</id>
                   <name>bintray-plugins</name>
                   <url>https://dl.bintray.com/dptinfoutln/public</url>
               </pluginRepository>
           </pluginRepositories>
           <id>bintray</id>
       </profile>
   </profiles>
   <activeProfiles>
       <activeProfile>bintray</activeProfile>
   </activeProfiles>
</settings>

Ce projet nécessite aussi le suivant comme dépendance:

git clone --recursive https://github.com/emmanuelbruno/cours-java-librarymanager-parent.git
cd cours-java-librarymanager-parent
mvn install
cd ..

Attention ce programme n’a pas été mis à jour, il faut un jdk8 Vous pouvez utiliser sdkman pour l’installer (sdk use java 8.0.252.hs-adp).

Le serveur REST :

git clone https://github.com/emmanuelbruno/cours-java-librarymanager-rest.git
cd cours-java-librarymanager-rest
mvn package && mvn exec:java

On peut consulter en JSON (attention au proxy web export NO_PROXY=127.0.0.1,localhost):

/t/testws$ curl -H "Accept: application/json"  http://localhost:9998/biblio/auteurs
{"auteur":[{"ID":"0","nom":"Martin","prenom":"Jean"},{"ID":"1","nom":"Durand","prenom":"Marie"}]}
/t/testws$ curl http://localhost:9998/biblio/auteur/1
{"ID":"1","nom":"Durand","prenom":"Marie"}

ou en XML

curl -H "Accept: application/xml"  http://localhost:9998/biblio/auteurs

et mettre à jour :

/t/testws$ curl -H "Content-Type: application/json" -X PUT http://localhost:9998/biblio/auteur\?nom\=Durand\&prenom\=Jean
/t/testws$ curl http://localhost:9998/biblio/auteurs
{"auteur":[{"ID":"0","nom":"Martin","prenom":"Jean"},{"ID":"1","nom":"Durand","prenom":"Marie"},{"ID":"2"},{"ID":"3","nom":"Durand","prenom":"Jean"}]}

La sérialisation est réalisée de façon transparente grâce à l’API JAXB. Les classes des entités peuvent être annotées pour contrôler la sérialisation : https://docs.oracle.com/javaee/7/tutorial/jaxrs-advanced007.htm

Attention aux cycles dans les références.

Jersey propose aussi une API très simple pour écrire des clients pour n’importe quel service rest. Etudier la classe BiblioClient du dernier exemple.

Vous pouvez lire la présentation de la mise en place JAX-RS avec JavaEE7 pour mieux comprendre les annotations des services Rest: http://docs.oracle.com/javaee/7/tutorial/jaxrs.htm

La documentation de Jersey : https://jersey.java.net/documentation/latest/user-guide.html