Partie 1 : Développement d’un service REST simple
1-2. Analyse des classes fournies
Classe testRS.java :
@Path("myRS1"): Définit le chemin de base pour cette ressource REST. Toutes les méthodes de cette classe seront accessibles sous/myRS1@GET: Indique que la méthodesayhello()répond aux requêtes HTTP GET- La méthode retourne directement une chaîne de caractères comme réponse
Classe MyApplication.java :
@ApplicationPath("/partie1"): Définit le chemin de base de l’application REST. C’est le préfixe commun à toutes les ressourcesgetClasses(): Enregistre les classes de ressources REST (icitestRS.class)- Cette classe sert de point d’entrée pour l’application JAX-RS
3. URL du service REST
En combinant les annotations :
- Chemin de l’application :
/partie1(depuis@ApplicationPath) - Chemin de la ressource :
/myRS1(depuis@Path) - Nom du WAR :
myprojectRStest.war
http://localhost:8080/myprojectRStest/partie1/myRS1
4. Compilation des classes
Commande de compilation :
javac -d WEBCONTENT/WEB-INF/classes -cp $JBOSS_LIB/javax/ws/rs/api/main/jboss-jaxrs-api_2.1_spec-2.0.0.Final.jar src/myRSproject/*.javaLes fichiers .class sont générés dans WEBCONTENT/WEB-INF/classes/myRSproject/.
5. Création du fichier WAR
Placement dans le répertoire WEBCONTENT :
cd WEBCONTENT
jar cvf myprojectRStest.war .Le fichier myprojectRStest.war est créé avec succès.
6-7. Déploiement sur WildFly
Copie du WAR vers le répertoire de déploiement :
cp myprojectRStest.war $JBOSS_HOME/standalone/deployments/Vérification dans la console d’administration WildFly (http://localhost:9990/console) :
Le service myprojectRStest.war apparaît dans la liste des déploiements avec le statut Enabled.
8. Test depuis un navigateur
Accès à l’URL :
http://localhost:8080/myprojectRStest/partie1/myRS1
Le service REST fonctionne correctement.
9. Test avec wget
Commande :
wget -qO- http://localhost:8080/myprojectRStest/partie1/myRS1Le service répond également correctement aux requêtes en ligne de commande.
Partie 2 : Développement et test avancés d’un service REST
a. Ajout de la méthode sayhello2
Modification de testRS.java :
package myRSproject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
@Path("myRS1")
public class testRS {
@GET
@Path("hello1")
public String sayhello() {
return " --- Test restful service : sayHello ---";
}
@GET
@Path("hello2")
public String sayhello2() {
return " --- Test restful service : sayHello2 ---";
}
}Modification de MyApplication.java pour changer le nom du WAR :
@ApplicationPath("/partie2")
public class MyApplication extends Application {
// ...
}Explication :
@Path("hello1")et@Path("hello2"): Ajoutent des sous-chemins aux méthodes- Les URLs complètes deviennent :
http://localhost:8080/mytestRS2/partie2/myRS1/hello1/http:/**/localhost:8080/mytestRS2/partie2/myRS1/hello2/
Déploiement :
Recompilation, création du WAR mytestRS2.war et déploiement sur WildFly.
Tests :
wget -qO- http://localhost:8080/mytestRS2/partie2/myRS1/hello1/
--- Test restful service : sayHello ---
wget -qO- http://localhost:8080/mytestRS2/partie2/myRS1/hello2/
--- Test restful service : sayHello2 ---Les deux méthodes sont accessibles sur leurs URLs respectives.
b. Paramètre dans l’URL avec @PathParam
Modification de testRS.java :
package myRSproject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
@Path("myRS1")
public class testRS {
@GET
@Path("hello1/{nom}")
public String sayhello(@PathParam("nom") String nom) {
return " --- Test restful service : Bonjour " + nom;
}
@GET
@Path("hello2")
public String sayhello2() {
return " --- Test restful service : sayHello2 ---";
}
}@Path("hello1/{nom}"): Définit un paramètre dynamique dans l’URL@PathParam("nom"): Injecte la valeur capturée dans le paramètre de la méthode- L’URL
http://localhost:8080/mytestRS3/partie1/myRS1/hello1/Dupontextrait “Dupont” comme valeur de{nom}
Test :
wget -qO- http://localhost:8080/mytestRS3/partie1/myRS1/hello1/Dupont
--- Test restful service : Bonjour DupontLe paramètre est correctement extrait et utilisé.
c. Paramètres de requête avec @QueryParam
Modification de testRS.java :
package myRSproject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
@Path("myRS1")
public class testRS {
@GET
@Path("hello1/{nom}")
public String sayhello(@PathParam("nom") String nom,
@QueryParam("prenom") String prenom,
@QueryParam("ville") String ville) {
return " --- Test restful service : Bonjour " + nom + " " + prenom + " de " + ville;
}
@GET
@Path("hello2")
public String sayhello2() {
return " --- Test restful service : sayHello2 ---";
}
}@QueryParam("prenom"): Extrait le paramètreprenomde la query string@QueryParam("ville"): Extrait le paramètrevillede la query string- Les paramètres de requête sont séparés par
?et&dans l’URL
Test :
wget -qO- "http://localhost:8080/mytestRS3/partie1/myRS1/hello1/Dupont?prenom=Bob&ville=Paris"
--- Test restful service : Bonjour Dupont Bob de ParisLes paramètres sont correctement extraits de la query string.
d. Méthode POST
Modification de testRS.java :
package myRSproject;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
@Path("myRS1")
public class testRS {
@GET
@Path("hello1/{nom}")
public String sayhello(@PathParam("nom") String nom,
@QueryParam("prenom") String prenom,
@QueryParam("ville") String ville) {
return " --- Test restful service : Bonjour " + nom + " " + prenom + " de " + ville;
}
@POST
@Path("hello2")
public String sayhello2() {
return " --- Test restful service : sayHello2 POST ---";
}
}@POST: La méthodesayhello2()répond maintenant aux requêtes HTTP POST au lieu de GET
Après recompilation et redéploiement, la méthode n’est plus accessible via GET mais uniquement via POST.
e. Test avec SOAP UI
Création d’un nouveau projet REST dans SOAP UI :
http://localhost:8080/mytestRS3/partie1/myRS1/hello2
- Méthode : POST
- URL :
http://localhost:8080/mytestRS3/partie1/myRS1/hello2 - Pas de body nécessaire
--- Test restful service : sayHello2 POST ---
f. Négociation de contenu avec @Produces
Modification complète de testRS.java :
package myRSproject;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.Produces;
@Path("myRS1")
public class testRS {
@GET
@Path("hello1/{nom}")
@Produces("text/html")
public String sayhello1(@PathParam("nom") String nom,
@QueryParam("prenom") String prenom,
@QueryParam("ville") String ville) {
return "<html><body><h1>--- Test GET - HTML : Bonjour " + nom + " " + prenom + " de " + ville + "</h1></body></html>";
}
@GET
@Path("hello1/{nom}")
@Produces("text/plain")
public String sayhello2(@PathParam("nom") String nom,
@QueryParam("prenom") String prenom,
@QueryParam("ville") String ville) {
return "--- Test GET - PLAIN Text : Bonjour " + nom + " " + prenom + " de " + ville;
}
@POST
@Path("hello1/{nom}")
@Produces("text/html")
public String sayhello3(@PathParam("nom") String nom,
@QueryParam("prenom") String prenom,
@QueryParam("ville") String ville) {
return "<html><body><h1>--- Test POST - HTML : Bonjour " + nom + " " + prenom + " de " + ville + "</h1></body></html>";
}
@POST
@Path("hello1/{nom}")
@Produces("text/plain")
public String sayhello4(@PathParam("nom") String nom,
@QueryParam("prenom") String prenom,
@QueryParam("ville") String ville) {
return "--- Test POST - PLAIN Text : Bonjour " + nom + " " + prenom + " de " + ville;
}
}Explication :
@Produces("text/html"): La méthode produit du contenu HTML@Produces("text/plain"): La méthode produit du texte brut- JAX-RS effectue la négociation de contenu : il sélectionne automatiquement la méthode appropriée selon l’en-tête HTTP
Acceptde la requête
Tests avec curl :
Test GET avec Accept: text/plain :
curl -H "Accept: text/plain" "http://localhost:8080/mytestRS3/partie1/myRS1/hello1/Martin?prenom=Alice&ville=Lyon"
--- Test GET - PLAIN Text : Bonjour Martin Alice de LyonTest GET avec Accept: text/html :
curl -H "Accept: text/html" "http://localhost:8080/mytestRS3/partie1/myRS1/hello1/Martin?prenom=Alice&ville=Lyon"
<html><body><h1>--- Test GET - HTML : Bonjour Martin Alice de Lyon</h1></body></html>Test POST avec Accept: text/plain :
curl -X POST -H "Accept: text/plain" "http://localhost:8080/mytestRS3/partie1/myRS1/hello1/Martin?prenom=Alice&ville=Lyon"
--- Test POST - PLAIN Text : Bonjour Martin Alice de LyonTest POST avec Accept: text/html :
curl -X POST -H "Accept: text/html" "http://localhost:8080/mytestRS3/partie1/myRS1/hello1/Martin?prenom=Alice&ville=Lyon"
<html><body><h1>--- Test POST - HTML : Bonjour Martin Alice de Lyon</h1></body></html>La négociation de contenu fonctionne parfaitement ! JAX-RS sélectionne automatiquement la bonne méthode selon la méthode HTTP (GET/POST) et le type de contenu demandé (text/plain ou text/html).
Partie 3 : Développement d’un client Java REST
4-5. Analyse du client testCL.java
package myclient;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.*;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
public class testCL {
public static void main(String[] args){
System.out.println("START MAIN ===================== ");
// Création du client JAX-RS
Client cl = ClientBuilder.newBuilder().build();
// Appel du service REST
String res = cl.target("http://127.0.0.1:8080/mytestRS3/partie1/myRS1/hello1/Bob?prenom=toto&ville=aubiere")
.request(MediaType.TEXT_PLAIN)
.get(String.class);
System.out.println(" Result: " + res);
// Fermeture du client
cl.close();
}
}Explication du code :
ClientBuilder.newBuilder().build(): Crée une instance de client JAX-RScl.target(url): Définit l’URL cible du service REST.request(MediaType.TEXT_PLAIN): Spécifie qu’on accepte du texte brut (en-tête Accept).get(String.class): Effectue une requête GET et récupère la réponse comme Stringcl.close(): Libère les ressources du client
6. Compilation et exécution
Compilation :
javac -d . -cp lib/jaxrs-ri/lib/*:lib/jaxrs-ri/ext/*:lib/jaxrs-ri/api/*:. ../src/myclient/*.javaExécution :
java -cp .:lib/jaxrs-ri/lib/*:lib/jaxrs-ri/ext/*:lib/jaxrs-ri/api/*:lib/javax.activation-api-1.2.0.jar myclient/testCLRésultat :
START MAIN =====================
Result: --- Test GET - PLAIN Text : Bonjour Bob toto de aubiere
Le client Java invoque avec succès le service REST
7. Extension du client pour tester les 4 méthodes
testCLComplete.java :
package myclient;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
public class testCLComplete {
public static void main(String[] args){
System.out.println("========== TEST CLIENT REST ==========\n");
Client cl = ClientBuilder.newBuilder().build();
String baseUrl = "http://127.0.0.1:8080/mytestRS3/partie1/myRS1/hello1/Durand?prenom=Sophie&ville=Toulouse";
// Test 1 : GET avec text/html
System.out.println("--- Test 1 : GET avec Accept: text/html ---");
String res1 = cl.target(baseUrl)
.request(MediaType.TEXT_HTML)
.get(String.class);
System.out.println("Résultat : " + res1 + "\n");
// Test 2 : GET avec text/plain
System.out.println("--- Test 2 : GET avec Accept: text/plain ---");
String res2 = cl.target(baseUrl)
.request(MediaType.TEXT_PLAIN)
.get(String.class);
System.out.println("Résultat : " + res2 + "\n");
// Test 3 : POST avec text/html
System.out.println("--- Test 3 : POST avec Accept: text/html ---");
Response response3 = cl.target(baseUrl)
.request(MediaType.TEXT_HTML)
.post(Entity.text(""));
String res3 = response3.readEntity(String.class);
System.out.println("Résultat : " + res3 + "\n");
// Test 4 : POST avec text/plain
System.out.println("--- Test 4 : POST avec Accept: text/plain ---");
Response response4 = cl.target(baseUrl)
.request(MediaType.TEXT_PLAIN)
.post(Entity.text(""));
String res4 = response4.readEntity(String.class);
System.out.println("Résultat : " + res4 + "\n");
cl.close();
System.out.println("========== FIN DES TESTS ==========");
}
}8. Compilation et test du client complet
Compilation :
javac -d . -cp lib/jaxrs-ri/lib/*:lib/jaxrs-ri/ext/*:lib/jaxrs-ri/api/*:. ../src/myclient/*.javaExécution :
java -cp .:lib/jaxrs-ri/lib/*:lib/jaxrs-ri/ext/*:lib/jaxrs-ri/api/*:lib/javax.activation-api-1.2.0.jar myclient/testCLCompleteRésultat :
========== TEST CLIENT REST ==========
--- Test 1 : GET avec Accept: text/html ---
Résultat : <html><body><h1>--- Test GET - HTML : Bonjour Durand Sophie de Toulouse</h1></body></html>
--- Test 2 : GET avec Accept: text/plain ---
Résultat : --- Test GET - PLAIN Text : Bonjour Durand Sophie de Toulouse
--- Test 3 : POST avec Accept: text/html ---
Résultat : <html><body><h1>--- Test POST - HTML : Bonjour Durand Sophie de Toulouse</h1></body></html>
--- Test 4 : POST avec Accept: text/plain ---
Résultat : --- Test POST - PLAIN Text : Bonjour Durand Sophie de Toulouse
========== FIN DES TESTS ==========
Tous les tests passent avec succès. Le client Java peut invoquer les 4 méthodes du service REST en utilisant différentes combinaisons de méthodes HTTP (GET/POST) et de types de contenu (text/html, text/plain).