soap Tutoriel
Se familiariser avec le savon
Recherche…
Remarques
Cette section fournit une vue d'ensemble de ce qu'est le savon et pourquoi un développeur peut vouloir l'utiliser.
Il devrait également mentionner tous les grands sujets dans le savon, et établir un lien avec les sujets connexes. La documentation de soap étant nouvelle, vous devrez peut-être créer des versions initiales de ces rubriques connexes.
Versions
Version | Date de sortie |
---|---|
1.1 | 2000-05-08 |
1.2 | 2003-06-24 |
Informations générales
SOAP est un acronyme pour Simple Object Access Protocol qui définit un protocole utilisé pour échanger des données via un appel de procédure à distance (RPC) avec d'autres services ou clients SOAP. Il est disponible en deux versions:
SOAP 1.2 rend obsolète SOAP 1.1 il est donc recommandé d'utiliser SOAP 1.2 si possible.
Il est souvent construit sur HTTP / S et rarement sur SMTP ou FTP, bien qu'il le prenne en charge selon le protocole. Bien que HTTP soit souvent utilisé comme protocole de transport sous-jacent, SOAP n'en utilise qu'un sous-ensemble limité. Pour envoyer des requêtes, il repose presque entièrement sur l'opération POST
de HTTP. GET
invocations GET
sont théoriquement possibles depuis la version 1.2, même si le document doit être transmis en tant que paramètre URI et peut donc dépasser une limite de 3000 caractères environ, ce qui est rejeté par la plupart des frameworks. De plus, les paramètres liés à la sécurité sont généralement définis dans un en-tête SOAP spécial.
Bien que SOAP et REST soient appelés services Web, ils sont très différents par nature. Certains frameworks font la distinction entre WS (pour les services basés sur SOAP) et RS (pour les services basés sur REST).
Le tableau suivant donne un bref aperçu des différences entre les deux types de services Web.
Aspect | SAVON | DU REPOS |
---|---|---|
la norme | SOAP , WSDL | Pas de standard, juste un style architectural |
Adressage des ressources | Indirect via les opérations SOAP | via des identificateurs de ressources uniques (URI) |
La gestion des erreurs | Message d'erreur SOAP | Codes de réponse d'erreur HTTP et éventuellement corps de réponse |
Représentation des données | XML | tous les encodages disponibles en HTTP |
Utilisation HTTP | Comme protocole de transport | Actions sur les ressources (CRUD) mappées sur les méthodes HTTP (GET, POST, PUT, DELETE, ...) |
Support transactionnel | via l'en-tête SOAP | en modélisant une transaction en tant que ressource |
Etat | Stateful (l'action SOAP fait partie de l'application) | Stateless (demandes autonomes) |
Découverte de service | UDDI / WSDL | Aucun en fait L'URI de démarrage de l'API doit renvoyer une liste de sous-API |
Méthode | Corps SOAP intérieur | Méthode HTTP |
Arguments de méthode | Défini par le schéma XML dans le WSDL | Soit via des en-têtes HTTP ou des paramètres Path / Query ou Matrix dans l'URI |
Transition d'état | Difficile à déterminer car pas directement basé sur des données | Invocation d'URI suivante |
Prise en charge de la mise en cache | Caching souvent pas désiré, | Simple comme défini par HTTP |
SAVON
Une requête SOAP consiste en une enveloppe SOAP qui doit contenir un élément body et peut contenir un élément d'en-tête facultatif. L'élément d'en-tête est utilisé pour transmettre certaines configurations au service, par exemple WS-Security peut définir que le message est crypté ou que WS-Coordination / WS-Transaction peut définir que le message doit être exécuté dans une transaction.
Une simple requête SOAP 1.2 via HTTP qui ajoute deux valeurs peut ressembler à ceci:
POST /calculator HTTP/1.1
Host: http://example.org
Content-Type: application/soap+xml; charset=utf-8
Content-Length: 224
<?xml version="1.0"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
<env:Body>
<m:AddValues xmlns:m="http://example.org/calculator">
<m:FirstValue>1</m:FirstValue>
<m:SecondValue>2</m:SecondValue>
</m:AddValues>
</env:Body>
</env:Envelope>
Une réponse à l'exemple de demande ci-dessus peut ressembler à ceci:
HTTP/1.1 200 OK
Content-Type: application/soap+xml; charset=utf-8
Content-Length: 329
<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
<soap:Body xmlns:m="http://www.example.org/calculator">
<m:AddValuesResponse>
<m:Result>3</m:Result>
</m:AddValuesResponse>
</soap:Body>
</soap:Envelope>
L'exemple ci-dessus a défini une requête qui invoquait la méthode AddValues
avec deux arguments, FirstValue
défini sur 1
et SecondValue
défini sur 2
. La requête a abouti à une exécution de cette méthode sur le serveur SOAP distant qui a calculé une valeur de 3
qui est encapsulée dans un élément de réponse distinct, qui est souvent le nom de la méthode invoquée plus une chaîne de Response
. L'inspection de la réponse peut conclure qu'il s'agit de la réponse à un précédent AddValue
méthode AddValue
.
Différences entre SOAP 1.1 et 1.2
SOAP 1.2 autorise d'autres protocoles de transport que HTTP tant que le cadre de liaison est pris en charge par le protocole.
SOAP 1.1 est basé sur XML 1.0, tandis que 1.2 est basé sur XML Infoset qui permet de sérialiser les messages SOAP avec d'autres sérialiseurs, puis le sérialiseur XML 1.0 par défaut utilisé par SOAP 1.1. Cela permet, par exemple, de sérialiser les messages sous forme de messages binaires et d'empêcher ainsi toute surcharge de la nature XML du message. En plus de cela, le mécanisme de sérialisation du protocole sous-jacent utilisé peut être déterminé via la liaison de données.
L’aspect interopérabilité a également été favorisé avec SOAP 1.2 en définissant un modèle de traitement plus spécifique que son prédécesseur, qui éliminait de nombreuses possibilités d’interprétation. SOAP with Attachment API (SAAJ), qui permet de travailler sur les messages SOAP 1.1 et 1.2, a aidé de nombreux développeurs d’infrastructure à traiter et à créer des messages.
Le W3C a publié un bref aperçu des principaux changements entre SOAP 1.1 et 1.2
Interopérabilité des services Web
L'interopérabilité des services Web (également appelée WS-I) est une directive d'interopérabilité régie par des entreprises bien connues telles qu'IBM, Microsoft, Oracle et HP, pour n'en citer que quelques-unes. Ces directives recommandent entre autres d’utiliser un seul élément racine dans le corps SOAP, même si le SOAP permet de contenir plusieurs éléments dans le corps.
WS-I consiste en
- WS-I Basic Profile aka WSI-BP
- Profil de sécurité de base WS-I
- Profil simple de reliure de savon
WSI-BP est disponible dans 4 versions différentes (v1.0 (2004)) , v1.1 (2006) , v1.2 (2010) et v2.0 (2010) et définit des directives d'interopérabilité pour les principales spécifications de service Web telles que SOAP, WSDL. et UDDI. Grâce à l'utilisation du langage WSDL (Web Services Description Language), les services SOAP peuvent décrire leurs opérations et méthodes prises en charge dans un ensemble cohérent à d'autres systèmes d'extrémité. WSI-BP utilise WSDL pour définir un ensemble plus étroit que le schéma WSDL ou SOAP complet définirait et élimine ainsi une partie de l'ambiguïté dans la spécification elle-même et améliore ainsi l'interopérabilité entre les points de terminaison.
WSDL
Afin de publier les opérations SOAP disponibles, leurs paramètres ainsi que les points de terminaison respectifs à appeler sur les clients, un autre document basé sur XML est appelé en abrégé Web Services Description Language
ou WSDL.
WSDL décrit le point de terminaison du service, la liaison des messages SOAP aux opérations, l'interface des opérations ainsi que leurs types aux clients. WSDL est, comme SOAP, disponible dans 2 versions qui diffèrent légèrement dans leur syntaxe, mais expriment presque la même sémantique au client.
WSDL 1.1
Une description WSDL 1.1 contient un service
, une binding
, un portType
et une section de message
. Il peut également importer ou définir des schémas dans le fichier WSDL, comme le montre un exemple de fichier WSDL correspondant à l'exemple de la calculatrice illustré ci-dessus:
<wsdl:definitions xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:calc="http://example.org/calculator"
xmlns:tns="http://example.org/calculatorService"
targetNamespace="http://example.org/calculatorService">
<!--
Abstract type definitions
-->
<wsdl:types>
<!--
<xs:schema>
<xs:import namespace="http://example.org/calculator" schemaLocation="calc/calculator.xsd" />
</xs:schema>
-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://example.org/calculator"
targetNamespace="http://example.org/calculator"
elementFormDefault="qualified"
attributeFormDefault="qualified">
<xs:element name="AddValuesRequest" type="tns:AddValuesType" />
<xs:element name="AddValuesResponse" type="tns:AddValuesResponseType" />
<xs:complexType name="AddValuesType">
<xs:sequence>
<xs:element name="FirstValue" type="xs:int" minOccurs="1" maxOccurs="1" />
<xs:element name="SecondValue" type="xs:int" minOccurs="1" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="AddValuesResponseType">
<xs:sequence minOccurs="1" maxOccurs="1">
<xs:element name="Result" type="xs:int" />
</xs:sequence>
</xs:complexType>
<xs:attribute name="Timestamp" type="xs:dateTime" />
<xs:element name="CalculationFailure">
<xs:complexType>
<xs:sequence>
<xs:element name="ErrorCode" type="xs:int" />
<xs:element name="Reason" type="xs:string" />
</xs:sequence>
<xs:attribute ref="tns:Timestamp" use="required" />
</xs:complexType>
</xs:element>
</xs:schema>
</wsdl:types>
<!--
Abstract message definitions
-->
<wsdl:message name="AddValuesRequest">
<wsdl:part name="in" element="calc:AddValuesRequest" />
</wsdl:message>
<wsdl:message name="AddValuesResponse">
<wsdl:part name="out" element="calc:AddValuesResponse" />
</wsdl:message>
<wsdl:message name="CalculationFault">
<wsdl:part name="fault" element="calc:CalculationFailure" />
</wsdl:message>
<!--
Abstract portType / interface definition
-->
<wsdl:portType name="CalculatorEndpoint">
<wsdl:operation name="AddValues">
<wsdl:documentation>Adds up passed values and returns the result</wsdl:documentation>
<wsdl:input message="tns:AddValuesRequest" />
<wsdl:output message="tns:AddValuesResponse" />
<wsdl:fault name="CalculationFault" message="tns:CalculationFault" />
</wsdl:operation>
</wsdl:portType>
<!--
Concrete binding definition
-->
<wsdl:binding name="CalculatorBinding" type="tns:CalculatorEndpoint">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="AddValues">
<soap:operation soapAction="http://example.org/calculator/AddValuesMessage" />
<wsdl:input>
<soap:body parts="in" use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body parts="out" use="literal" />
</wsdl:output>
<wsdl:fault name="CalculationFault">
<soap:fault name="CalculationFault" use="literal" />
</wsdl:fault>
</wsdl:operation>
</wsdl:binding>
<!--
Concrete service definition
-->
<wsdl:service name="CalculatorService">
<wsdl:port name="CalculatorServicePort" binding="tns:CalculatorBinding">
<soap:address location="http://localhost:8080/services/calculator" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Une section de service
définit les points de terminaison concrets que le service écoutera pour les demandes entrantes. La section de binding
lie une opération à un style concret et définit les formats de message attendus par le serveur ou auxquels le client peut s'attendre.
La section abstraite est composée d'un bloc portType
qui définit les opérations offertes par le service et les messages échangés. Les messages sont spécifiés dans leur bloc on et liés aux types de schéma dont les arguments et les valeurs de retour sont des instances. Les messages peuvent déclarer des paramètres ou renvoyer des valeurs devant être in
, out
ou inout
. Alors que les deux premiers sont assez simples à comprendre, ce dernier imite le comportement des arguments transmis par référence. Comme certaines références ne prennent pas en charge les références, cet effet est souvent simulé via certains gestionnaires.
WSDL 2.0
La même calculatrice peut être décrite dans WSDL 2.0 comme ceci:
<?xml version="1.0" encoding="utf-8" ?>
<wsdl:description xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://www.w3.org/ns/wsdl"
xmlns:soap="http://www.w3.org/ns/wsdl/soap"
xmlns:calc="http://example.org/calculator"
xmlns:tns="http://example.org/calculatorService"
targetNamespace="http://example.org/calculatorService">
<!--
Abstract type definitions
-->
<wsdl:types>
<!--
<xs:schema>
<xs:import namespace="http://example.org/calculator" schemaLocation="calc/calculator.xsd" />
</xs:schema>
-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://example.org/calculator"
targetNamespace="http://example.org/calculator"
elementFormDefault="qualified"
attributeFormDefault="qualified">
<xs:element name="AddValuesRequest" type="tns:AddValuesType" />
<xs:element name="AddValuesResponse" type="tns:AddValuesResponseType" />
<xs:complexType name="AddValuesType">
<xs:sequence>
<xs:element name="FirstValue" type="xs:int" minOccurs="1" maxOccurs="1" />
<xs:element name="SecondValue" type="xs:int" minOccurs="1" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="AddValuesResponseType">
<xs:sequence minOccurs="1" maxOccurs="1">
<xs:element name="Result" type="xs:int" />
</xs:sequence>
</xs:complexType>
<xs:attribute name="Timestamp" type="xs:dateTime" />
<xs:element name="CalculationFault">
<xs:complexType>
<xs:sequence>
<xs:element name="ErrorCode" type="xs:int" />
<xs:element name="Reason" type="xs:string" />
</xs:sequence>
<xs:attribute ref="tns:Timestamp" use="required" />
</xs:complexType>
</xs:element>
</xs:schema>
</wsdl:types>
<!--
Abstract interface
-->
<wsdl:interface name="CalculatorInterface">
<wsdl:fault name="fault" element="calc:CalculationFault" />
<wsdl:operation name="AddValues" pattern="http://www.w3.org/ns/wsdl/in-out" style="http://www.w3.org/ns/wsdl/style/iri" wsdl:safe="true">
<wsdl:documentation>Adds up passed values and returns the result</wsdl:documentation>
<wsdl:input messageLabel="in" element="calc:AddValuesRequest" />
<wsdl:output messageLabel="out" element="calc:AddValuesResponse" />
<wsdl:outfault messageLabel="fault" ref="tns:fault" />
</wsdl:operation>
</wsdl:interface>
<!--
Concrete binding definition
-->
<wsdl:binding name="CalculatorBinding" interface="tns:CalculatorInterface" type="http://www.w3.org/ns/wsdl/soap" soap:protocol="http://www.w3.org/2003/05/soap/bindings/HTTP/">
<wsdl:operation ref="tns:AddValues" soap:mep="http://www.w3.org/2003/05/soap/mep/soap-response" />
<wsdl:fault ref="tns:fault" soap:code="soap:Sender" />
</wsdl:binding>
<!--
Concrete service definition
-->
<wsdl:service name="CalculatorService" interface="tns:CalculatorInterface">
<wsdl:endpoint name="CalculatorEndpoint" binding="tns:CalculatorBinding" address="http://localhost:8080/services/calculator" />
</wsdl:service>
</wsdl:description>
Différences entre WSDL 1.1 et 2.0
Un aperçu graphique des différences entre les deux versions peut être vu dans l'image ci-dessous.
( Source )
Comme on peut le voir sur l'image, la section de message
a été supprimée, qui est maintenant contenue dans la section interface
. En outre, certains des éléments ont été renommés, d'autres ont une syntaxe différente, mais en général, les deux versions de WSDL font la même chose, la version 2.0 nécessitant un peu moins de temps d'écriture que la version 1.1.
Outre le faible encombrement de la définition des services SOAP via WSDL 2.0, la nouvelle version fournit également des fonctionnalités permettant de définir les services REST, même si WSDL 2.0 ou même WADL ne sont PAS recommandés pour les services RESTful.
Quel style préférer
La section de liaison WSDL décrit comment le service est lié au protocole de messagerie SOAP. L'exemple ci-dessus utilise le document
comme style de liaison, ce qui permet de structurer le corps SOAP comme nous le souhaitons, tant que la sortie résultante est une instance XML valide. Il s'agit du style de liaison par défaut, souvent appelé Message-Oriented style
.
Contrairement au style de document
, les corps de requête de style RPC
doivent contenir à la fois le nom de l'opération et l'ensemble des paramètres de la méthode. La structure de l'instance XML est donc prédéfinie et ne peut pas être modifiée.
En plus du style de liaison, la section de liaison définit également un modèle de traduction pour les liaisons aux messages SOAP au nom du literal
ou du encoded
. La différence entre les deux est que ce modèle literal
doit se conformer à une structure XSD définie par l'utilisateur, qui peut être utilisée pour valider les demandes et les réponses, tandis que le modèle encoded
doit utiliser des types de données XSD tels que xs:integer
ou xs:string
en échange, ne doit donc pas se conformer à un schéma défini par l'utilisateur. Cela rend cependant plus difficile la validation du corps du message ou la transformation du message via XSLT vers un autre format.
La combinaison du style de liaison avec le modèle d'utilisation permet en réalité 4 résultats de message différents. Une 5ème entrée est ajoutée à la liste couramment utilisée (mais ne fait pas vraiment partie de la norme).
- RPC / encodé
- RPC / littéral
- Document / encodé
- Document / littéral
- Document / littéral (enveloppé)
Dans le style document / littéral de la messagerie, il existe un modèle appelé document encapsulé / littéral. Ceci est juste un modèle et ne fait pas partie de la spécification WSDL. Ce modèle est mentionné dans JSR 224 (JAX-WS: API Java pour les services Web basés sur XML). ( Source )
La section ci-dessous donne un aperçu des différences concernant la déclaration WSDL ou la déclaration de schéma et leur impact sur le format de message SOAP résultant en modifiant le style de liaison ou en utilisant des définitions de modèle.
RPC / encodé
WSDL:
...
<wsdl:message name="AddValues">
<wsdl:part name="FirstValue" type="xsd:int" />
<wsdl:part name="SecondValue" type="xsd:int" />
</wsdl:message>
<wsdl:message name="AddValuesResponse">
<wsdl:part name="Result" type="xsd:int" />
</wsdl:message>
<wsdl:portType name="CalculatorEndpoint">
<wsdl:operation="AddValues">
<wsdl:input message="AddValues" />
<wsdl:output message="AddValuesResponse" />
</wsdl:operation>
</wsdl:portType>
<!-- binding style set to 'RPC' and use to 'encoded' -->
...
Demande SOAP
<soap:envelope>
<soap:body>
<AddValues>
<FirstValue xsi:type="xsd:int">1</FirstValue>
<SecondValue xsi:type="xsd:int">2</SecondValue>
</AddValues>
</soap:body>
</soap:envelope>
Réponse SOAP
<soap:envelope>
<soap:body>
<AddValuesResponse>
<Result xsi:type="xsd:int">3</Result>
</AddValuesResponse>
</soap:body>
</soap:envelope>
Avantages
- WSDL simple
- Nom de l'opération et éléments disponibles dans la requête et la réponse
Les inconvénients
- Déclaration explicite des types XSI
- Difficile à valider
- Non conforme à WS-I
RPC / littéral
WSDL:
...
<wsdl:message name="AddValues">
<wsdl:part name="FirstValue" type="xsd:int" />
<wsdl:part name="SecondValue" type="xsd:int" />
</wsdl:message>
<wsdl:message name="AddValuesResponse">
<wsdl:part name="Result" type="xsd:int" />
</wsdl:message>
<wsdl:portType name="CalculatorEndpoint">
<wsdl:operation="AddValues">
<wsdl:input message="AddValues" />
<wsdl:output message="AddValuesResponse" />
</wsdl:operation>
</wsdl:portType>
<!-- binding style set to 'RPC' and use to 'literal' -->
...
Demande SOAP
<soap:envelope>
<soap:body>
<AddValues>
<FirstValue>1</FirstValue>
<SecondValue>2</SecondValue>
</AddValues>
</soap:body>
</soap:envelope>
Réponse SOAP
<soap:envelope>
<soap:body>
<AddValuesResult>
<Result>3</Result>
</AddValuesResult>
</soap:body>
</soap:envelope>
Avantages
- WSDL simple
- Nom de l'opération et éléments disponibles dans la requête et la réponse
- Aucune spécification de type XSI nécessaire
- WS-I conforme
Les inconvénients
- Difficile à valider
Document / encodé
Ne fait donc aucun sens omis.
Document / littéral
WSDL:
...
<types>
<schema>
<element name="FirstValueElement" type="xsd:int" />
<element name="SecondValueElement" type="xsd:int" />
<element name="ResultValueElement" type="xsd:int" />
</schema>
</types>
<wsdl:message name="AddValues">
<wsdl:part name="FirstValue" element="FirstValueElement" />
<wsdl:part name="SecondValue" element="SecondValueElement" />
</wsdl:message>
<wsdl:message name="AddValuesResponse">
<wsdl:part name="Result" element="ResultValueElement" />
</wsdl:message>
<wsdl:portType name="CalculatorEndpoint">
<wsdl:operation="AddValues">
<wsdl:input message="AddValues" />
<wsdl:output message="AddValuesResponse" />
</wsdl:operation>
</wsdl:portType>
<!-- binding style set to 'Document' and use to 'literal' -->
...
Demande SOAP
<soap:envelope>
<soap:body>
<FirstValueElement>1</FirstValueElement>
<SecondValueElement>2</SecondValueElement>
</soap:body>
</soap:envelope>
Réponse SOAP
<soap:envelope>
<soap:body>
<ResultElement>3</ResultElement>
</soap:body>
</soap:envelope>
Avantages
- Pas de codage de type XSI
- Capable de valider le corps
- WS-I conforme aux restrictions
Les inconvénients
- WSDL est plus compliqué en raison de la définition XSD supplémentaire
- Le nom de l'opération est perdu
- WS-I n'autorise qu'un enfant dans le corps SOAP
Document / littéral (enveloppé)
WSDL:
...
<types>
<schema>
<element name="AddValues">
<complexType>
<sequence>
<element name="FirstValue" type="xsd:int" />
<element name="SecondValue" type="xsd:int" />
</sequence>
</complexType>
</element>
<element name="AddValuesResponse">
<complexType>
<sequence>
<element name="ResultValue" type="xsd:int" />
</sequence>
</complexType>
</element>
</schema>
</types>
<wsdl:message name="AddValues">
<wsdl:part name="in" element="AddValues" />
</wsdl:message>
<wsdl:message name="AddValuesResponse">
<wsdl:part name="out" element="AddValuesResponse" />
</wsdl:message>
<wsdl:portType name="CalculatorEndpoint">
<wsdl:operation="AddValues">
<wsdl:input message="AddValues" />
<wsdl:output message="AddValuesResponse" />
</wsdl:operation>
</wsdl:portType>
<!-- binding style set to 'Document' and use to 'literal' -->
...
Demande SOAP
<soap:envelope>
<soap:body>
<AddValues>
<FirstValue>1</FirstValue>
<SecondValue>2</SecondValue>
</AddValues>
</soap:body>
</soap:envelope>
Réponse SOAP
<soap:envelope>
<soap:body>
<AddValuesResponse>
<Result>3</Result>
</AddValuesResponse>
</soap:body>
</soap:envelope>
Avantages
- Pas de codage de type XSI
- Capable de valider le corps
- Nom de l'opération et éléments disponibles dans la requête et la réponse
- WS-I conforme
Les inconvénients
- WSDL est plus compliqué en raison de la définition XSD supplémentaire
UDDI
Universal Description, Discovery and Integration (UDDI)
est une initiative industrielle créée en 2000 qui sert de registre de pages jaunes basé sur XML pour les services Web, ce qui aide à trouver des services qui résolvent des tâches spécifiques. Afin de trouver un service approprié, un service doit d'abord être enregistré auprès d'un registre de services Web tel que l'UDDI.
UDDI fonctionne sur l'échange de messages SOAP et permet d'accéder aux documents WSDL pouvant être utilisés pour appeler le service Web réel.
L'UDDI fournit des critères de recherche comme
- identifiant d'entreprise
- nom de l'entreprise
- lieu d'affaires
- Catégorie Business
- type de service par nom
- URL de découverte
Cependant, un inconvénient majeur de l'UDDI actuel est qu'il ne permet d'utiliser qu'un seul critère dans une instruction de recherche. Certains implémenteurs ont donc modularisé leurs implémentations UDDI pour permettre aux requêtes de générer plusieurs UDDI simultanément, puis d'agréger les résultats renvoyés.
En pratique, cependant, UDDI n'est pas souvent utilisé. Certains disent même qu'UDDI est mort depuis qu'IBM, Microsoft et SAP ont fermé leurs services UDDI en 2005 .
Notes complémentaires:
SOAP / WSDL fournit un large éventail de prise en charge des outils et permet également de générer dynamiquement des classes de stub pour les clients et les serveurs, car le type de messages et de données échangés est bien défini via les schémas XSD incorporés ou liés.
Bien que WSDL 2.0 ait moins de définition des services Web, certaines langues n’ont pas encore adopté la nouvelle norme. Par exemple, en Java, les outils les plus répandus, tels que wsimport
(à partir d’Oracle / Sun) ou wsdl2java
(à partir d’Apache CXF), ne peuvent pas gérer correctement les descriptions WSDL 2.0. Par conséquent, pour des raisons de compatibilité, il est toujours recommandé d'utiliser WSDL 1.1. Si vous avez besoin de développer un service SOAP basé sur WSDL 2.0 en Java, jetez un oeil à wsdl2java
du projet Apache Axis2 .
De nos jours, les services d'API basés sur HTTP, qui associent des invocations d'opérations HTTP à des URI compréhensibles par l'homme et certaines personnalisations du protocole, sont plus populaires. Ils permettent aux services basés sur REST de respecter pleinement les recommandations. ou propres protocoles de niveau octet, comme par exemple OFTP2 .
SOAP est toujours utile si vous ne pouvez pas associer votre tâche directement aux ressources, comme le font les services de base HTTP / REST, car la tâche à accomplir représente naturellement une action ou doit définir une certaine sémantique de transaction. De plus, si vous ne disposez pas des ressources nécessaires pour définir ou implémenter votre propre protocole, il est probablement préférable d'utiliser SOAP. SOAP est particulièrement utile si vous devez gérer l'orchestration car la description WSDL associée à UDDI permet de combiner les services de manière dynamique.
Webservice open source Java Client for Weather service disponible sur http://www.webserviceX.NET
package com.test.ws.example;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
/*
* WSDL url : http://www.webservicex.com/globalweather.asmx?WSDL
* Endpoint URL: http://www.webservicex.com/globalweather.asmx */
public class WSClient {
public static void main(String args[]) {
try {
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
SOAPConnection soapConnection = soapConnectionFactory.createConnection();
// Generate SOAP request XML
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
MimeHeaders header = soapMessage.getMimeHeaders();
header.setHeader("SOAPAction", "http://www.webserviceX.NET/GetCitiesByCountry");
SOAPPart soapPart = soapMessage.getSOAPPart();
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration("web", "http://www.webserviceX.NET");
SOAPBody soapBody = envelope.getBody();
SOAPElement soapBodyElem = soapBody.addChildElement("GetCitiesByCountry", "web");
SOAPElement soapBodyElem1 = soapBodyElem.addChildElement("CountryName", "web");
soapBodyElem1.addTextNode("INDIA");
soapMessage.saveChanges();
soapMessage.writeTo(System.out);
// Call webservice endpint
String url = "http://www.webservicex.com/globalweather.asmx";
SOAPMessage soapResponse = soapConnection.call(soapMessage, url);
Source sourceContent = soapResponse.getSOAPPart().getContent();
// Print SOAP response
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
System.out.println("Response SOAP Message \n");
StreamResult result = new StreamResult(System.out);
transformer.transform(sourceContent, result);
soapConnection.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Création d'un service Web simple et de clients avec JAX-WS (document / littéral)
Ceci est le répertoire du projet.
- Une interface de noeud final de service
Nous allons d'abord créer une interface de point de terminaison de service. L'annotation javax.jws.WebService @WebService
définit la classe en tant que noeud final de service Web.
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import javax.jws.soap.SOAPBinding.Use;
// Service Interface with customize targetNamespace
@WebService(targetNamespace = "http://hello-soap/ws")
@SOAPBinding(style = Style.DOCUMENT, use=Use.LITERAL) //optional
public interface HelloSoap {
@WebMethod String getHelloSoap(String name);
}
- Implémentation du point final du service (SEI)
Ensuite, nous allons créer une implémentation de point de terminaison de service. Nous allons créer une interface explicite en ajoutant l'élément endpointInterface
à l'annotation @WebService
dans la classe d'implémentation. Voici un ensemble de règles 28.1.1 Conditions requises pour un noeud final JAX-WS que les noeuds finaux JAX-WS doivent suivre. La méthode getHelloSoap renvoie un message d'accueil au client avec le nom qui lui est transmis.
import javax.jws.WebService;
// Customized Service Implementation (portName,serviceName,targetNamespace are optional)
@WebService(portName = "HelloSoapPort", serviceName = "HelloSoapService",
endpointInterface = "com.wonderland.hellosoap.HelloSoap", targetNamespace = "http://hello-soap/ws")
public class HelloSoapImpl implements HelloSoap {
@Override
public String getHelloSoap(String name) {
return "[JAX-WS] Hello : " + name;
}
}
- Editeur de noeud final de service Web
import javax.xml.ws.Endpoint;
public class HelloSoapPublisher {
public static void main(String[] args) {
// creating web service endpoint publisher
Endpoint.publish("http://localhost:9000/ws/hello-soap", new HelloSoapImpl());
}
}
- Les étapes suivantes, nous allons lancer
HelloSoapPublisher.java
comme application Java. Ensuite, nous verrons le fichier WSDL en demandant l'URLhttp://localhost:9000/ws/hello-soap?wsdl
dans un navigateur Web.
http: // localhost: 9000 / ws / hello-soap? wsdl
Si le format de données XML est affiché dans le navigateur Web, nous sommes prêts à passer à l'étape suivante.
Remarque:
Si vous obtenez un message d'erreur quelconque, vous devrez peut-être utiliser l'outilwsgen
pour générer les artefacts portables JAX-WS nécessaires. Nous ne sommes pas couverts par l'outilwsgen
ici.
- Client de service Web
Dernière étape, nous allons créer un client qui accède à notre service publié.
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
public class HelloSoapClient {
public static void main(String[] args) throws Exception {
// create wsdl url
URL wsdlDocumentUrl = new URL("http://localhost:8000/ws/hello-soap?wsdl");
QName helloSoapService = new QName("http://hello-soap/ws", "HelloSoapService");
// create web service
Service service = Service.create(wsdlDocumentUrl, helloSoapService);
// get object of pointed service port
HelloSoap helloSoap = service.getPort(HelloSoap.class);
// testing request
System.out.println(helloSoap.getHelloSoap("Soap "));
}
}
Sortie: [JAX-WS] Hello : Soap
Remarque: le numéro de port a été changé à 8000
dans notre client de service Web. La raison en est que j'ai utilisé Eclipse IDE, un outil de TCP/IP monitor
intégré pour tracer les messages (Plus d'informations: Comment suivre un message SOAP dans Eclipse IDE ). Pour les tests fonctionnels, essayez SoapUI | Test fonctionnel pour les API SOAP et REST .