Service Web REST en Java
Introduction
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 ressourcePOST
: création d’une ressourceDELETE
: suppression d’une ressourcePUT
: 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.
Pratique avec Jersey et Grizzly
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"}]}
Des paramètres et des retour en XML, JSON, ...
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.
Client en Java
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.
Pour aller plus loin
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