====== Handlers JAX-WS ====== L'objectif de ce TP est de mettre en place des intercepteurs (//handlers//) JAX-WS. Sauf indication contraire((classe Client)), les développements se feront dans le projet ''services''. Ce TP est à rendre pour le mercredi 28 novembre 2012 [[http://spiralconnect.univ-lyon1.fr/spiral/spiral.html#/activities/goto_folder/1929168|via spiral]]. Sont attendus le zip contenant les projets (sans les répertoire target) et les tests soapUI, ainsi qu'un fichier README.txt avec les nom et numéro d'étudiants des binômes, ainsi que toute information à porter à la connaissance du correcteur du TP. ===== Exemple ===== Créer une classe ''tiw5.metier.services.handlers.SimpleLogHandler'' contenant le code suivant: package tiw5.metier.services.handlers; import javax.xml.ws.handler.LogicalHandler; import javax.xml.ws.handler.LogicalMessageContext; import javax.xml.ws.handler.MessageContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class SimpleLogHandler implements LogicalHandler { private final static Logger LOG = LoggerFactory.getLogger(SimpleLogHandler.class); @Override public void close(MessageContext ctx) { } @Override public boolean handleFault(LogicalMessageContext ctx) { LOG.warn("faute"); return true; } @Override public boolean handleMessage(LogicalMessageContext ctx) { boolean outbound = (Boolean) ctx.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); LOG.info("message "+(outbound?"sortant":"entrant")); return true; } } Créer un fichier ''src/main/resources/tiw5/metier/services/soap/handler-chains.xml'' contenant: tiw5.metier.services.handlers.SimpleLogHandler tiw5.metier.services.handlers.SimpleLogHandler Ajouter l'annotation ''@HandlerChain(file="handler-chains.xml")'' dans la classe ''tiw5.metier.services.soap.JPATestService'', déployer les services sous JBoss et tester l'affichage dans les log en appelant le service avec SOAPUI. ===== Clients ===== Créer une classe ''tiw5.modele.Client'' dans le projet ''modele'': package tiw5.modele; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @Entity public class Client { /** * L'identifiant du client. */ @Id @GeneratedValue private int id; /** * 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() { return nom; } public void setNom(String nom) { this.nom = nom; } public int getId() { return id; } public double getCompte() { return compte; } public void setCompte(double compte) { this.compte = compte; } } Si le besoin s'en fait sentir, ne pas hésiter à créer une classe ''tiw5.modele.dao.ClientDAO'' pour gérer les clients. ===== Handler de log ===== Mettre en place une chaîne de //handlers// pour le service de location que vous avez implémenté pour le [[enseignement:tp:sw:jaxrs-jaxws|TP3]] et y ajouter le handler de Log utilisé pour le service JPATestService. Modifier ce handler 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 location 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 ''services'' 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 location. 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. 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 ctx.setScope("client", Scope.APPLICATION);