Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Prochaine révision
Révision précédente
enseignement:tp:sw:handlers-rest:2014 [2014/10/28 19:23]
ecoquery créée
enseignement:tp:sw:handlers-rest:2014 [2014/11/04 13:18] (Version actuelle)
ecoquery [Rendu]
Ligne 1: Ligne 1:
-====== Handlers JAX-WS ======+====== JAX-RS, Handlers & Filters ======
  
 L'objectif de ce TP est de mettre en place: L'objectif de ce TP est de mettre en place:
   - des service REST en utilisant JAX-RS   - des service REST en utilisant JAX-RS
   - des intercepteurs (//handlers//) JAX-*S.    - des intercepteurs (//handlers//) JAX-*S. 
-Sauf indication contraire((classe Client)), les développements se feront dans le projet ''service''.+ 
 +Les développements se feront dans le projet ''services'' du [[enseignement:tp:sw:fournisseur:2014|TP3]]. Si les services du TP3 ne sont pas pleinement fonctionnels, on pourra se contenter d'en faire une version simplifiée (//e.g.// sans persistance) pour les besoins de ce TP. 
 + 
 +Dans les dépendances du projet on utilisera une version >= 3 pour CXF.
  
 ==== Rendu ==== ==== Rendu ====
  
  
-Ce TP est à rendre pour le dimanche 20/10/2013. Le rendu se fera par l'intermédiaire d'un projet forge (on fera attention a bien donner au moin le rôle "reporter" à Emmanuel Coquery et à Lionel Medini) contenant:+Ce TP est à rendre pour le mercredi 17/11/2014 <del>05/11/2014</del>. Le rendu se fera par l'intermédiaire d'un projet forge (on fera attention a bien donner au moins le rôle "reporter" à Emmanuel Coquery et à Lionel Medini) contenant:
     * le projet maven mis à jour par vos soins (//**sans**// le répertoire ''target'')     * le projet maven mis à jour par vos soins (//**sans**// le répertoire ''target'')
-    * un fichier README.txt contenant au moins les noms, prénoms et numéros d'étudiants du binôme/trinôme. Toute autre information à transmettre aux enseignants (e.g. justifications de choix techniques) se fera dans ce fichier.+    * un fichier README.txt contenant au moins les noms, prénoms et numéros d'étudiants du binôme. Toute autre information à transmettre aux enseignants (e.g. justifications de choix techniques) se fera dans ce fichier
 + 
 +L'identifiant du projet forge (de la forme pxxxxxx-nomprojet) est à saisir dans [[http://tomusss.univ-lyon1.fr|Tomuss]], dans l'UE Tiw5 WebServices, dans la case ''TP4_F''. On fera attention à [[http://mercurial.selenic.com/wiki/Tag|tagger]] la révision correspondant au rendu avec le tag ''TP4''.  
 + 
 +===== Services REST ===== 
 + 
 +Créer une classe sw.film.vod.services.ClientResource qui implémente les opérations CRUD((Create, Read, Update, Delete)) pour la classe client (en utilisant un ClientDAO).
  
-L'identifiant du projet forge (e la forme pxxxxxx-nomprojet) est à saisir dans [[http://tomusss.univ-lyon1.fr|Tomuss]], dans l'UE Tiw5 WebServices, dans la case ''FORGE_TP4''On fera attention à [[http://mercurial.selenic.com/wiki/Tag|tagger]] la révision correspondant au rendu avec le tag ''TP4'' +Annoter cette classe via l'[[http://docs.oracle.com/javaee/7/api/index.html?javax/ws/rs/Path.html||API JAX-RS]] pour en faire une ressource REST. 
-===== Exemple =====+  * [[http://docs.oracle.com/javaee/7/tutorial/doc/jaxrs.htm#GIEPU|Tutorial Java EE]] 
 +  * [[http://cxf.apache.org/docs/jax-rs-basics.html|doc CXF]]
  
-Créer une classe ''sw.wine.services.handlers.SimpleLogHandler'' contenant le code suivant:+Déployer la ressource aux côtés des services du [[enseignement:tp:sw:fournisseur:2014|TP3]] en utilisant CXF. 
 + 
 +===== Handlers JAX-WS ===== 
 + 
 +==== Exemple ==== 
 + 
 +Créer une classe ''sw.film.vod.services.handlers.SimpleLogHandler'' contenant le code suivant:
 <code java SimpleLogHandler.java> <code java SimpleLogHandler.java>
-package sw.wine.services.handlers;+package sw.film.vod.services.handlers;
  
 import javax.xml.ws.handler.LogicalHandler; import javax.xml.ws.handler.LogicalHandler;
Ligne 52: Ligne 68:
 </code> </code>
  
-Créer un fichier ''src/main/resources/sw/wine/services/handler-chains.xml'' contenant:+Créer un fichier ''src/main/resources/sw/film/vod/services/handler-chains.xml'' contenant:
 <code xml handler-chains.xml> <code xml handler-chains.xml>
 <?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
Ligne 58: Ligne 74:
   <handler-chain>   <handler-chain>
     <handler>     <handler>
-      <handler-name>sw.wine.services.handlers.SimpleLogHandler</handler-name> +      <handler-name>sw.film.vod.services.handlers.SimpleLogHandler</handler-name> 
-      <handler-class>sw.wine.services.handlers.SimpleLogHandler</handler-class>+      <handler-class>sw.film.vod.services.handlers.SimpleLogHandler</handler-class>
     </handler>     </handler>
     <!-- handler>     <!-- handler>
Ligne 69: Ligne 85:
 </code> </code>
  
-Ajouter l'annotation ''<nowiki>@HandlerChain(file="handler-chains.xml")</nowiki>'' dans la classe ''sw.wine.services.WineStorage'', déployer le service et tester l'affichage dans les log en appelant le service avec SOAPUI.+Ajouter l'annotation ''<nowiki>@HandlerChain(file="handler-chains.xml")</nowiki>'' dans la classe ''sw.film.vod.services.VODService''((ou tout autre nom que vous aurez choisi pour la classe d'implémentation du service)), déployer le service et tester l'affichage dans les log en appelant le service avec SOAPUI.
  
-===== Clients =====+==== Ajout d'information ====
  
-Créer une classe ''sw.wine.model.user.Client'' dans le projet ''modele''+Créer un nouveau handler qui récupère dans le header SOAP la valeur de l'élément ''client-id'' et l'injecte dans le contexte (propriété "client-id")Modifier le handler de log pour afficher cette propriété si elle est présenteAjouter ce handler dans la chaîne d'interception et modifier le test soapUI de votre service de livraison pour y intégrer le nouveau header et tester.
-<code java Client.java> +
-package sw.wine.model.user;+
  
-import javax.persistence.Entity; +==== Récupération de l'objet client ====
-import javax.persistence.GeneratedValue; +
-import javax.persistence.Id;+
  
-@Entity +Créer un handler logique d'authentification qui ajoute une propriété ''client'' contenant un objet ''Client'' correspondant à la propriété ''client-id''. Si le client n'existe pas, le handler interdit l'accès au service. 
-public class Client {+
  
- /** +Ajouter l'intercepteur dans la chaîne des services et tester. On pourra créer un ensemble de clients pour le test via un test JUnit dans le projet ''services'' en utilisant JPA, ou via toute autre méthode, e.g. utilisation de script d'init SQL, etc.
- * L'identifiant du client. +
- */ +
- @Id +
- @GeneratedValue +
- private int id;+
  
- /** +==== Débit du compte client ====
- * Le nom du client+
- */ +
- private String nom; +
-  +
- /** +
- * La quantité d'argent que le client possède sur son compte de location. +
- */ +
- private double compte;+
  
- public String getNom() { +Ajouter un champ ''double valeurCompte'' dans la classe Client.
- return nom; +
- }+
  
- public void setNom(String nom+Modifier l'API du service (interface ''IVODService''de façon à supprimer le paramètre clientId de la méthode ''access''.
- this.nom = nom; +
- }+
  
- public int getId() { +Ajouter un champ de type ''javax.xml.ws.WebServiceContext'' dans la classe d'implémentation du service de vod. 
- return id; +Annoter ce champ avec ''@Resource'' afin que le contexte soit injecté via IoC.  
- }+La méthode ''getMessageContext()'' permet alors de récupérer le contexte du message et les propriétés qui ont été ajoutées par les handlers.  
 +Modifier le code métier du service pour: 
 +  - récupérer l'objet Client depuis le contexte 
 +  - débiter le compte du client
  
- public double getCompte() { 
- return compte; 
- } 
  
- public void setCompte(double compte) { +<note tip>Seules les propriétés dont le scope est MessageContext.Scope.APPLICATION peuvent être accédées dans le bean qui code le serviceIl faut donc penser à changer le scope de la propriété ''client'' dans le handler d'authentification via <code java>ctx.setScope("client", Scope.APPLICATION);</code></note>
- this.compte = compte; +
-+
-  +
-+
-</code> +
-Si le besoin s'en fait sentir, ne pas hésiter à créer une classe ''sw.wine.model.user.dao.ClientDAO'' pour gérer les clients.+
  
-===== Handler de log ===== 
  
-Mettre en place une chaîne de //handlers// pour le service de livraison (une des versions utilisant CXF) que vous avez implémenté pour le [[enseignement:tp:sw:fournisseur:2013|TP3]] et y ajouter le handler de Log utilisé pour le service WineStorage.+===== Filters JAX-RS =====
  
-Pour cela on créera un nouveau module ''handlers'' en lancant <code>mvn archetype:generate -DinteractiveMode=false -DartifactId=handlers -DgroupId=sw.wine</code> +On souhaite sécuriser la ressource REST Client. Utiliser l'[[http://cxf.apache.org/docs/jax-rs-basics.html#JAX-RSBasics-Server|API Filters de JAX-RS]] pour vérifier la présence d'un mot de passe correspondant à celui de l'utilisateur pour toute modification de ce dernier.
-On modifiera ensuite le pom du projet handlers en: +
-  * supprimant les tag ''<version>'' et ''<groupId>'' dans ''<project>''((mais pas dans ''<parent>'')) +
-  * et en ajoutant dans ''<parent>'': <code><relativePath>..</relativePath></code> +
-Enfin on ajoutera les dépendances ''handlers'' <''model'', ''services'' <''handlers'', ''wine-service'' <- ''handlers''.+
  
-Déplacer ensuite la classe du handler de log dans le projet ''handlers'' 
  
-Modifier le handler de log pour afficher le nom de l'élément principal du message transmis. 
- 
-===== Ajout d'information ===== 
- 
-Créer un nouveau handler qui récupère dans le header SOAP la valeur de l'élément ''client-id'' et l'injecte dans le contexte (propriété "client-id"). Modifier le handler de log pour afficher cette propriété si elle est présente. Ajouter ce handler dans la chaine d'interception et modifier le test soapUI de votre service de livraison pour y intégrer le nouveau header et tester. 
- 
-===== Récupération de l'objet client ===== 
- 
-Créer un handler logique d'authentification qui ajoute une propriété ''client'' contenant un objet ''Client'' correspondant à la propriété ''client-id''. Si le client n'existe pas, le handler interdit l'accès au service. Ajouter l'intercepteur dans la chaine des services et tester. On créera un ensemble de clients pour le test via un test JUnit dans le projet ''wine-service'' en utilisant JPA.  
- 
-===== Débit du compte client ===== 
- 
-Ajouter un champ de type ''javax.xml.ws.WebServiceContext'' dans la classe d'implémentation du service de livraison. 
-Annoter ce champ avec ''@Resource'' afin que le contexte soit injecté via IoC.  
-La méthode ''getMessageContext()'' permet alors de récupérer le contexte du message et les propriétés qui ont été ajoutées par les handlers.  
-Modifier le code métier du service pour, en plus, débiter le compte du client.  
-<note tip>Seules les propriétés dont le scope est MessageContext.Scope.APPLICATION peuvent être accédées dans le bean qui code le service. Il faut donc penser à changer le scope de la propriété ''client'' dans le handler d'authentification via <code java>ctx.setScope("client", Scope.APPLICATION);</code></note>