Services Web (SOAP) - Plateforme e
Transcription
Services Web (SOAP) - Plateforme e
INSA - ASI InfoRep : WebServices Informatique Répartie Web Services Alexandre Pauchet INSA Rouen - Département ASI BO.B.RC.18, [email protected] 1/43 INSA - ASI InfoRep : WebServices Plan 1 Introduction 2 SOAP 3 WSDL 4 Implémentation avec JBoss 5 Passage d’objets et exceptions 6 Alternative : Axis 7 Références 2/43 INSA - ASI InfoRep : WebServices Introduction 3/43 (1/4) Objectif Limitations de Corba et RMI Impossibilité de faire transiter des informations à travers un pare-feu Solution Le protocole internet (Http) comme protocole de transport XML pour le formatage des données Mode RPC sur Internet INSA - ASI InfoRep : WebServices Introduction (2/4) Vocabulaire Service Web : composant logiciel distribué qui utilise le protocole internet pour le transport des requêtes (HTTP ou SMTP) et XML pour le formatage des données UDDI (Universal Description, Discovery and Integration) : annuaire des services web WSDL (Web Service Description Language) : langage reposant sur XML qui permet de décrire un service web XML-RPC : protocole de Service Web sans état (développé par Dave Winer de Frontier et Userland) SOAP (Simple Object Access Protocol) : protocole de Service Web avec état (développé par Microsoft, DevelopMentor et UserlanSoftware) 4/43 INSA - ASI InfoRep : WebServices Introduction (3/4) XML-RPC versus SOAP “XML-RPC est une spécification et un ensemble d’implémentations permettant de faire du RPC avec http et le langage XML, exactement de la même façon que SOAP. En fait, les histoires de XML-RPC et de SOAP sont intimement liées. À l’origine XML-RPC était appelé informellement SOAP par ces concepteurs dont l’instigateur était Dave Winer. Les premiers développement étaient fait en collaboration entre les équipes de UserLand, DevelopMentor et Microsoft. Mais déçu par la tournure des choses, Dave Winer décide de séparer sa spécification de celle de Microsoft. Cela aboutit à XML-RPC. Rapidement Microsoft va jouer le standard de fait, en introduisant son SOAP dans un groupe de travail du W3C. Aujourd’hui SOAP supporte plus de fonctionnalités que XML-RPC (pas toujours utiles ?) et c’est une spécification en devenir alors que XML-RPC est figé.” Jean-Marc Pierson http://www.if.insa-lyon.fr/chercheurs/jmpierson/Reseau4IF/ Projets/ProgrammationDistribuee/soap/soap.htm 5/43 INSA - ASI InfoRep : WebServices Introduction (4/4) Acteurs Nombreux acteurs Microsoft .Net Apache : Axis (2), CXF Sun : JAX-WS et Metro JBoss Autres implémentations open-source etc. Interopérabilité Services des uns utilisables par les autres WS-I.org : Web Service Interoperability organization 6/43 INSA - ASI SOAP InfoRep : WebServices (1/5) Organisation d’un message SOAP Requête HTTP En-tête HTTP POST /soap Contenu/longueur Message HTTP Enveloppe SOAP En-tête Corps 7/43 INSA - ASI SOAP InfoRep : WebServices (2/5) Exemple de requête Http contenant un message SOAP POST /axis/HelloService.jws HTTP/1.0 Content-Type: text/xml; charset=utf-8 Accept: application/soap+xml, application/dime, multipart/related, text/* User-Agent: Axis/1.0 Host: localhost:5555 Cache-Control: no-cache Pragma: no-cache SOAPAction: "" Content-Length: 403 <?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Body> <sayHello soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <arg0 xsi:type="xsd:string">Toto</arg0> </sayHello> </soapenv:Body> </soapenv:Envelope> 8/43 INSA - ASI SOAP InfoRep : WebServices (3/5) Réponse SOAP à une requête SOAP HTTP/1.1 200 OK Set-Cookie: JSESSIONID=A71CF66D85AD77975999A0F8A4B71BA5; Path=/axis Content-Type: text/xml; charset=utf-8 Date: Wed, 09 Apr 2003 10:10:06 GMT Server: Apache Coyote/1.0 Connection: close <?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Body> <sayHelloResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <sayHelloReturn xsi:type="xsd:string">Hello, Toto</sayHelloReturn> </sayHelloResponse> </soapenv:Body> </soapenv:Envelope> 9/43 INSA - ASI InfoRep : WebServices SOAP (4/5) Sérialisation des données SOAP utilise les types définis dans XML Schema : Cf. http://www.w3.org/TR/xmlschema-2/ Cf. Cours de Document On a donc la possibilité de sérialiser : des types simples (près d’une quarantaine) des structures (xs:complexType) On a aussi la possibilité de sérialiser des tableaux en utilisant un XML Schema qui définit l’élément Array et l’attribut arrayType : http://www.w3.org/2001/09/soap-encoding 10/43 INSA - ASI SOAP InfoRep : WebServices (5/5) 11/43 INSA - ASI InfoRep : WebServices WSDL (1/4) Description Fichier XML décrivant un service web Opérations (services) disponibles Accession (adresse, protocole du Service Web, etc.) Format des messages échangés entre client et serveur Pour invoquer le service Pour interpréter un résultat Rien sur sa sémantique (ce qu’il fait) 12/43 INSA - ASI WSDL InfoRep : WebServices 13/43 (2/4) Interface/Implémentation Description WSDL Des types sont utilisés dans des messages, associés dans des portTypes, reliés à un protocole par des bindings formant des Services Web. INSA - ASI InfoRep : WebServices WSDL (3/4) Contenu types : contient les définitions de types utilisant un système de typage donné (comme XSD) message : décrit les noms et types d’un ensemble de champs à transmettre (paramètres d’invocation, valeur du retour, etc.) portType : décrit un ensemble d’opérations. Chaque opération a 0 ou 1 message en entrée, 0 ou plusieurs messages en sortie binding : spécifie une liaison d’un <porttype> à un protocole concret (SOAP1.1, etc.). Un <porttype> peut avoir plusieurs liaisons ! port : spécifie un point d’entrée (endpoint) comme la combinaison d’un <binding> et d’une adresse réseau service : une collection de points d’entrée (endpoint) relatifs 14/43 INSA - ASI InfoRep : WebServices WSDL (4/4) Outils Générateur WSDL à partir de déploiements SOAP ou EJB, Générateur de proxy SOAP à partir de WSDL Toolkits (wsdl2java / java2wsdl, etc.) Propriétaires (non normalisés) Ex (Axis) : <PATH-TO-AXIS2>/bin/wsdl2java.sh Ex (JBoss) : <PATH-TO-JBOSS>/bin/wsconsume.sh 2 approches Approche Top-Down : WSDL =⇒ code (à remplir) + stubs. Approche identique à Sun RPC, Corba, etc. Approche Bottom-up : Web Service =⇒ WSDL 15/43 INSA - ASI InfoRep : WebServices Implémentation avec JBoss (1/14) Serveur/Client avec JBoss Approche Bottom-up 1 Développer une interface (Description du service) 2 Développer une implémentation de cette interface (POJO : Plain Old Java Object) 3 Développer le Service Web (POJO + web.xml → archive.war) 4 Déployer le Service Web sur un serveur JBoss 5 Télécharger le fichier wsdl 6 Générer le Stub client 7 Développer le client 16/43 INSA - ASI InfoRep : WebServices Implémentation avec JBoss 17/43 (2/14) Annotations Java Intégrées au JDK 1.5, elles permettent d’ajouter des Méta-informations au code (i.e. marquer des éléments Java afin de leur ajouter une propriété) Peuvent être utilisées sur n’importe quel type d’élément Java (package, class, attribut, méthode, paramètre, etc.) Plusieurs annotations peuvent être utilisées sur un même élément Non prises en compte par la JVM (mais présente dans le .class) : il faut écrire du code ou des outils qui utilise ces informations Utilisées à la compilation ou à l’exécution Utilisation : @ suivi du mot-clef correspondant à l’annotation L’API Java 5.0 propose de base 3 annotations : @Deprecated, @Override et @SuppressWarnings Déclaration et création de nouvelles annotations : comme une interface en utilisant le mot-clef @interface (java.lang.annotation.Annotation) Possibilité de passer des informations à une annotation : nom=valeur INSA - ASI InfoRep : WebServices Implémentation avec JBoss (3/14) Exemple d’annotations Java Exemple public @interface MaNouvelleAnnotation { } Exemple @MaNouvelleAnnotation @SuppressWarnings("deprecation") public class maClasse { @UneAutreAnnotation(champ="type") public String texte = "Texte"; @Override @SuppressWarnings({"deprecation","unckeked"}) public String toString() { return this.texte; } } 18/43 INSA - ASI InfoRep : WebServices Implémentation avec JBoss 19/43 (4/14) Services Web JBoss et annotations Les outils intégrés à JBoss pour générer du WSDL à partir de code Java utilisent les annotations pour simplifier le code à produire : Moins de code à écrire Génération automatique des descripteurs de déploiement INSA - ASI InfoRep : WebServices Implémentation avec JBoss (5/14) Interface helloWebServices.HelloWorldWS.java package helloWebService; import import import import javax.jws.WebService; javax.jws.WebMethod; javax.jws.WebParam; javax.jws.soap.SOAPBinding; @WebService(name="HelloWorldWS") // PortType @SOAPBinding(style=SOAPBinding.Style.RPC) // Binding public interface HelloWorldWS { @WebMethod(action="sayHello") // Operation public String sayHello(@WebParam(name = "name") String name); } 20/43 INSA - ASI InfoRep : WebServices Implémentation avec JBoss (6/14) Implémentation POJO du service helloWebServices.HelloWorldWSImpl.java package helloWebService; import javax.jws.WebService; @WebService(endpointInterface="helloWebService.HelloWorldWS") // Port (EndPoint : lien vers une Servlet) public class HelloWorldWSImpl implements HelloWorldWS { @Override public String sayHello(String name) { return "Hello " + name + " !"; } } 21/43 INSA - ASI InfoRep : WebServices Implémentation avec JBoss (7/14) Déclaration du service META-INF/web.xml <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <servlet> <servlet-name>HelloWorldWS</servlet-name> <servlet-class>helloWebService.HelloWorldWSImpl</servlet-class> </servlet> <servlet-mapping> <servlet-name>HelloWorldWS</servlet-name> <url-pattern>/HelloWorldWS</url-pattern> </servlet-mapping> </web-app> 22/43 INSA - ASI InfoRep : WebServices Implémentation avec JBoss (8/14) Archivage et déploiement Archivage : jar -cf HelloWorldWebService.war WEB-INF Fichier HelloWorldWebService.war : HelloWorldWebService.war |_ WEB-INF | |_ web.xml | |_ classes | |_ helloWebServices | |_ HelloWorldWS.class | |_ HelloWorldWSImpl.class |_ META-INF |_ MANIFEST.MF Déploiement de HelloWorldWebService.war dans deploy 23/43 INSA - ASI InfoRep : WebServices Implémentation avec JBoss Récupération du WSDL : (9/14) http://localhost:8080/HelloWorldWebService/HelloWorldWS?wsdl 24/43 INSA - ASI InfoRep : WebServices Implémentation avec JBoss 25/43 (10/14) Stub client Récupération du stub client $JBOSS_HOME/bin/wsconsume.sh http://localhost:8080/HelloWorldWebService/HelloWorldWS?wsdl Permet de télécharger le fichier wsdl de description du service et de générer et compiler à la volée les fichiers suivants : HelloWorldWS.java HelloWorldWSImplService.java L’option -k permet de conserver les fichiers .java temporaires INSA - ASI InfoRep : WebServices Implémentation avec JBoss (11/14) Fichiers générés à la volée hellowebservices.HelloWorldWS.java package hellowebservice; import import import import import javax.jws.WebMethod; javax.jws.WebParam; javax.jws.WebResult; javax.jws.WebService; javax.jws.soap.SOAPBinding; /** * This class was generated by Apache CXF 2.4.6 * 2014-03-19T15:59:37.109+01:00 * Generated source version: 2.4.6 * */ @WebService(targetNamespace = "http://helloWebService/", name = "HelloWorldWS") @SOAPBinding(style = SOAPBinding.Style.RPC) public interface HelloWorldWS { @WebResult(name = "return", targetNamespace = "http://helloWebService/", partName = "return") @WebMethod(action = "sayHello") public java.lang.String sayHello( @WebParam(partName = "name", name = "name") java.lang.String name ); } 26/43 INSA - ASI InfoRep : WebServices Implémentation avec JBoss (12/14) Fichiers générés à la volée hellowebservices.HelloWorldWSImplService.java package hellowebservice; import import import import import import import java.net.MalformedURLException; java.net.URL; javax.xml.namespace.QName; javax.xml.ws.WebEndpoint; javax.xml.ws.WebServiceClient; javax.xml.ws.WebServiceFeature; javax.xml.ws.Service; /** * This class was generated by Apache CXF 2.4.6 * 2014-03-19T15:59:37.138+01:00 * Generated source version: 2.4.6 * */ @WebServiceClient(name = "HelloWorldWSImplService", wsdlLocation = "http://localhost:8080/HelloWorldWebService/HelloWorldWS?wsdl", targetNamespace = "http://helloWebService/") public class HelloWorldWSImplService extends Service { ... 27/43 INSA - ASI InfoRep : WebServices Implémentation avec JBoss (13/14) Fichiers générés à la volée hellowebservices.HelloWorldWSImplService.java ... public HelloWorldWSImplService() { super(WSDL_LOCATION, SERVICE); } ... /** * * @return * returns HelloWorldWS */ @WebEndpoint(name = "HelloWorldWSImplPort") public HelloWorldWS getHelloWorldWSImplPort() { return super.getPort(HelloWorldWSImplPort, HelloWorldWS.class); } ... 28/43 INSA - ASI InfoRep : WebServices Implémentation avec JBoss (14/14) Client client.Client.java import hellowebservice.HelloWorldWS; import hellowebservice.HelloWorldWSImplService; public class Client { public static void main(String[] args) throws Exception { HelloWorldWS hello = (new HelloWorldWSImplService()).getHelloWorldWSImplPort(); System.out.println(hello.sayHello(args[0])); } } 29/43 INSA - ASI InfoRep : WebServices Passage d’objets et exceptions (1/9) Utilisation de javabeans Contrainte sur les passages d’objet : javabeans Par valeur uniquement, en argument comme en valeur en retour Constructeur sans argument Accesseurs et modifieurs sur les attributs (get et set sur chacun des attributs) À l’aide de wsconsume, génération de : ObjectFactory : pour créer des objets côté client Une classe par Objet transmis Gestion des exceptions Totalement transparente pour l’utilisateur 30/43 INSA - ASI InfoRep : WebServices Passage d’objets et exceptions (2/9) Interface institute.Secretariat.java package institute; import import import import javax.jws.WebService; javax.jws.WebMethod; javax.jws.WebParam; javax.jws.soap.SOAPBinding; @WebService(name="Secretariat") @SOAPBinding(style=SOAPBinding.Style.RPC) public interface Secretariat { @WebMethod(action="register") public Student register(@WebParam(name="candidate") Candidate candidate, @WebParam(name="testValue") int testValue) throws ChaineVide; } 31/43 INSA - ASI InfoRep : WebServices Passage d’objets et exceptions (3/9) Implémentation POJO du service institute.SecretariatWS.java package institute; import javax.jws.WebService; @WebService(endpointInterface="institute.Secretariat") public class SecretariatWS implements Secretariat { @Override public Student register(Candidate candidate, int testValue) throws ChaineVide { if(candidate.getName().length()==0) throw new ChaineVide(); return new Student(candidate.getName(), 10/testValue); } } 32/43 INSA - ASI InfoRep : WebServices Passage d’objets et exceptions (4/9) Passage de javabeans institute.Candidate.java institute.Student.java package institute; package institute; public class Candidate { private String name; public class Student { private String name; private int testValue; public Candidate () { this.name = ""; } public Student() { this.name = ""; this.testValue = 0; } public Candidate (String name) { this.name = name; } public Student(String name, int testValue) { this.name = name; this.testValue = testValue; } public void setName(String name) { this.name = name; } public void setName(String name) { this.name = name; } public String getName() { return this.name; } public void setTestValue(int testValue) { this.testValue = testValue; } } public String getName() { return this.name; } public int getTestValue() { return this.testValue; } } 33/43 INSA - ASI InfoRep : WebServices Passage d’objets et exceptions Exception déclarée institute.ChaineVide.java package institute; public class ChaineVide extends Exception { public ChaineVide(){ super("String vide !"); } } (5/9) 34/43 INSA - ASI InfoRep : WebServices Passage d’objets et exceptions (6/9) Déclaration et déploiement du service META-INF/web.xml University.war University.war <?xml version="1.0" encoding="ISO-8859-1"?> |_ WEB-INF <!DOCTYPE web-app PUBLIC | |_ web.xml "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" | |_ classes "http://java.sun.com/dtd/web-app_2_3.dtd"> | |_ institute <web-app> | |_ Secretariat.class <servlet> | |_ SecretariatWS.class <servlet-name>UniversityWS</servlet-name> | |_ Candidate.class <servlet-class>institute.SecretariatWS</servlet-class> | |_ Student.class </servlet> | |_ ChaineVide.class <servlet-mapping> |_ META-INF <servlet-name>UniversityWS</servlet-name> |_ MANIFEST.MF <url-pattern>/UniversityWS</url-pattern> </servlet-mapping> </web-app> 35/43 INSA - ASI InfoRep : WebServices Passage d’objets et exceptions (7/9) Récupération du Stub client $JBOSS_HOME/bin/wsconsume.sh http://localhost:8080/University/UniversityWS?wsdl Génération à la volée des fichiers : ObjectFactory.java package-info.java Candidate.java Student.java ChaineVide.java ChaineVide Exception.java Secretariat.java SecretariatWS.java Remarque Seule la partie correspondant à un javabean est générée ! 36/43 INSA - ASI InfoRep : WebServices Passage d’objets et exceptions (8/9) Classe Candidate générée institute.Candidate.java (généré) package institute; * Sets the value of the name property. * * @param value * allowed object is * {@link String } * */ public void setName(String value) { this.name = value; } ... @XmlType(name = "candidate", propOrder = { "name" }) public class Candidate { } protected String name; /** * Gets the value of the name property. * * @return * possible object is * {@link String } * */ public String getName() { return name; } 37/43 INSA - ASI InfoRep : WebServices Passage d’objets et exceptions (9/9) Client client.Client.java import institute.*; public class Client { public static void main(String[] args) throws java.lang.Exception { Secretariat secretariat = (new institute.SecretariatWSService()).getSecretariatWSPort(); Candidate candidate = new Candidate(); if(args.length == 2) candidate.setName(args[0]); Student student = secretariat.register(candidate, Integer.parseInt(args[args.length-1])); System.out.println(student.getName() + " est inscrit. Valeur de test : " + student.getTestValue()); } } 38/43 INSA - ASI InfoRep : WebServices Alternative : Axis Description d’Apache Axis Développé par la fondation Apache Contribution d’HP, IBM, Macromédia, etc. Open-source Java, donc multi-plateformes Conforme aux dernières évolutions de SOAP Peut être utilisé avec tout serveur Web J2EE http://ws.apache.org/axis2 axis2.war : utilisation conjointe avec tomcat (Attention : incompatible avec les dernières versions de JBoss qui utilisent leur propre système de Web Services) serveur autonome 39/43 INSA - ASI InfoRep : WebServices Alternative : Axis Développement avec Axis2 Méthode 1 Développer un service POJO 2 Développer le Service Web (services.xml + POJO → archive) 3 Déployer le Service Web 4 Télécharger le fichier wsdl 5 Générer le Stub client 6 Implémenter le client 40/43 INSA - ASI InfoRep : WebServices Alternative : Axis Stub client Récupération du stub client sh <PATH-TO-AXIS2>/bin/wsdl2java.sh -uri http://localhost:8080/axis2/services/XXX?wsdl -p client.stubs -d adb Permet de télécharger le fichier wsdl de description du service et de générer à la volée les fichiers suivants : XXXStub.java XXXCallbackHandler.java À la compilation du client : -extdirs <PATH-TO-AXIS2>/lib/ À l’exécution du client : -Djava.ext.dirs=<PATH-TO-AXIS2>/lib/ Nécessite la version de développement d’Axis2 41/43 INSA - ASI InfoRep : WebServices 42/43 Alternative : Axis Arguments Paramètres multiples Il faut initialiser les paramètres un par un (setParam0, setParam1) Contraintes sur les passages d’objet En argument comme en valeur en retour Nécessité d’avoir des accesseurs et modifieurs sur les attributs (get et set sur chacun des attributs) Utilisation de la classe XXXStub.ObjetTransmis, mais transtypage (cast) impossible ⇒ création d’un nouvel objet à la réception INSA - ASI InfoRep : WebServices Références Services Web open Source : D. Ayala, C. Browne, V. Chopra, P. Sarang, K. Asphangar, T. McAllister Campus Press - ISBN : 2-7440-1507-5 Java Web Services : D. A. Chappell, T. Jewel O’Reilly - ISBN : 0-596-00269-6 http://community.jboss.org/wiki/jbossws-userguide 43/43