Une problématique courante dans la mise en place de systèmes d'information et de savoir
comment échanger des informations entre plusieurs processus. Cette problématique est souvent résumée par la notion
d'interopérabilité. D'un point de vue technique,
l'interopérabilité est rendue plus complexe par un ou plusieurs facteurs :
les programmes sont écrits dans des langages différents
les processus s'exécutent sur des machines différentes
les machines appartiennent à des réseaux différents
Avant l'an 2000, on trouve des solutions telles que Sun RPC, CORBA, DCOM, RMI.
À partir des années 2000, le succés des réseaux IP, de HTTP
et de XML apporte une nouvelle perspective : définir
un protocole d'échange de messages XML via HTTP entre deux processus.
Ce protocole originellement défini par Microsoft puis maintenu par le W3 s'appelle SOAP.
Depuis SOAP a été enrichi de nombreuses spécifications et l'ensemble de ces technologies sont désignées sous le terme WS-*.
SOAP : structure des messages
SOAP est une recommandation pour l'échange de messages au format XML entre un expéditeur (SOAP sender)
et un destinataire (SOAP receiver). La structure des messages SOAP est identique qu'elle provienne de l'expéditeur (requête) ou du destinataire (réponse).
Un message est constitué par une enveloppe (SOAP envelope) qui peut contenir un en-tête (SOAP header) et ensuite une
charge utile (SOAP body).
Pour une utilisation avec le protocole HTTP, le message doit être envoyé avec la méthode POST à l'URL du service (appelée aussi endpoint)
Du fait de son utilisation exclusive du XML pour la composition des messages, une bonne compréhension de SOAP
nécessite une connaissance approfondie de XML (Cf.le complément au cours sur XML).
SOAP définit un format pour un type de réponse particulière : une SOAP fault.
Une SOAP fault signale un problème lors du traitement du service.
Web Service Description Language (WSDL)
La condition pour utiliser un service Web SOAP est de connaître les opérations disponibles et le format des
messages autorisés en entrée et/ou en sortie de ses opérations. WSDL (Web Service Description Language)
est un langage XML permettant la description complète d'un service Web. Ainsi un fichier WSDL est analysable par
programme et on trouve des outils dans différents langages de programmation pour générer
du code (les stubs) facilitant le développement des programmes (client ou serveur).
Développer un service Web SOAP
On distingue deux approches pour développer un service Web WS-* :
Contract first
On définit le contrat du service en spécifiant le WSDL et on utilise des outils pour générer le code des stubs.
Contract last
On développe le service et on utilise des outils pour générer le WSDL.
Pour tester ce service Web, vous pouvez utiliser le client SoapUI.
Implémenter des services Web avec JAX-WS
Depuis Java 6, l'environnement d'exécution Java inclut JAX-WS qui est l'API permettant d'implémenter des services
Web et JAXB (Java API for XML Binding) permettant d'associer une classe Java à une représentation XML.
L'implémentation d'un service Web passe par l'écriture et l'implémentation d'une SEI (Service Endpoint Implementation).
Cette interface et son implémentation peuvent être fournies par le développeur ou peuvent être générées à partir d'un ficher WSDL (Cf. ci-dessous).
Cette SEI permet de gérer un échange de messages comme celui-ci :
Nous allons maintenant décrire les annotations Java utilisées pour transformer la classe HelloService en service Web :
Indique le support SOAP pour le service. Les informations données par les attributs de cette annotation correspondent pour la plupart à celles que
l'on trouve dans la section binding du WSDL.
Cette annotation possède entre-autres les attributs suivants :
style
Définit s'il s'agit d'un service RPC ou Document.
parameterStyle
Détermine si un paramètre de la méthode représente la charge utile du message SOAP (le body) ou si ce paramètre doit être encapsulé (wrapped) dans un élément racine
XML nommé d'après le nom de l'opération SOAP.
Cette annotation permet d'associer le paramètre de la méthode sur laquelle elle porte à une partie d'un message (l'élément part de message dans le WSDL).
Elle possède les attributs suivants :
name
le nom de l'élement XML
targetNamespace
l'espace de nom de l'élement XML
header
un booléan indiquant si l'élement XML correspond à un en-tête ou s'il s'agit du corps du message.
mode
Il s'agit d'une énumération pouvant prendre les valeurs IN, OUT ou INOUT.
Pour les valeurs OUT et INOUT, le type du paramètre est obligatoirement de type
javax.xml.ws.Holder<T>.
IN signifie que l'élément est extrait du message de l'expéditeur tandis que OUT indique que l'élément
fait partie de la réponse.
Cette annotation a la même sémantique que l'annotation @WebParam sauf qu'elle est ajoutée à la méthode et qu'elle porte sur la valeur de retour de la méthode.
Elle possède les attributs suivants :
name
le nom de l'élement XML
targetNamespace
l'espace de nom de l'élement XML
header
un booléan indiquant si l'élement XML correspond à un en-tête ou s'il s'agit du corps du message.
Déployer un service Web dans un serveur d'application Java EE
Pour déployer un service Web développé avec JAX-WS, soit vous disposez d'un serveur d'application
Java EE (comme Glassfish ou TomEE), soit vous ne disposez que d'un conteneur de Servlet (comme Tomcat ou Jetty).
Pour un déploiement dans un serveur d'application Java EE, il suffit d'embarquer votre implémentation dans
une application Web Java et de déployer cette application. Le serveur d'application s'occupe du reste...
Pour un déploiement dans un conteneur de Servlet, il faut incorporer une implémentation de JAX-WS dans votre application Web
et se conformer à sa documentation car JAX-WS ne définit pas de standard de configuration et de déploiement.
Il existe plusieurs implémentations de JAX-WS : Metro, CXF...
Pour un déploiement en utilisant l'implémentation Metro sous Tomcat, vous pouvez suivre ce tutoriel.
Les outils Java de génération
Java → WSDL (Contract last)
L'utilitaire wsgen
livré avec le JDK peut générer un fichier WSDL à partir d'une classe compilée.
WSDL → Java (Contract first)
L'utilitaire wsimport livré avec le JDK
peut générer toutes les classes Java nécessaires à l'implémentation d'un client ou d'un service à partir d'un fichier WSDL.
Consommer un service Web avec JAX-WS
Une application cliente d'un service Web SOAP peut utiliser un stub.
Un stub est une classe générée qui masque la complexité des échanges de messages
avec le serveur.
Il est possible de créer un client à partir du code généré par wsimport.
Le code précédent pose un problème : le client utilise l'URL du service
spécifiée dans la section wsdl:service du WSDL. Il est souvent
utile de pouvoir changer dynamiquement l'URL du endpoint.
Excercice : Écrire un programme client d'un service Web
Par exemple, vous pouvez écrire un programme qui accepte le nom d'une ville en paramètre et qui affiche la température obtenue pour cette ville après un appel au service Web.
Excercice : Écrire un service Web
Reprenez l'implémentation de la SEI donnée en exemple plus haut et créez une application Web Java EE incorporant ce service. Déployez ensuite cette application dans un serveur
d'application comme TomEE Plus. Vérifiez que le service fonctionne en utilisant par exemple SoapUI.
Vous pouvez ensuite écrire un programme Java client de votre service.