Copyright © 2001-2007 Nicholas Quaine.
Home   Bases   Côté-Serveur   Côté-Client   Démos   FAQ   Ressources
Bases
1. Qu'est-ce que SOAP?
2. Services Web
3. Messages SOAP
4. Eléments du système
Specifications
SOAP 1.1
WSDL 1.1
UDDI 2.0
XML 1.0

Précédent   1    2    3    4    Suivant
Les Bases de SOAP
3. Messages SOAP

La syntaxe d'un message SOAP est décrite en détail dans http://www.w3.org/TR/SOAP/
Voici un résumé et quelques exemples pour les impatients.

Un message SOAP valide est un document XML au bon format. (pour plus de détails sur XML et sur le format correct, visitez le site http://www.w3.org/XML/ ). Le prologue XML peut être présent, mais dans ce cas, ne doit contenir qu'une déclaration XML (c-à-d. qu'il ne doit contenir ni référence à un DTD, ni instruction XML). Le message doit utiliser l'enveloppe SOAP et les namespaces d'encodage SOAP, et doit avoir la forme suivante:

  • Une déclaration XML (optionnelle), suivie de
  • une Enveloppe SOAP (l'élément racine) qui est composée de:
    • Une En-tête SOAP (optionnel)
    • Un Corps SOAP

Un dialogue RPC encodé par SOAP contient un message de requête et un message de réponse. Considérons la méthode d'un service simple qui double la valeur d'un entier donné.
Signature de la Methode

  int doubleAnInteger ( int numberToDouble );
Requête

  <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
  <SOAP-ENV:Envelope
   SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
   xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
   xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
   xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
   xmlns:xsd="http://www.w3.org/1999/XMLSchema">
	<SOAP-ENV:Body>
		<ns1:doubleAnInteger
		 xmlns:ns1="urn:MySoapServices">
			<param1 xsi:type="xsd:int">123</param1>
		</ns1:doubleAnInteger>
	</SOAP-ENV:Body>
  </SOAP-ENV:Envelope>
Réponse

  <?xml version="1.0" encoding="UTF-8" ?>
  <SOAP-ENV:Envelope
   xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
   xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
   xmlns:xsd="http://www.w3.org/1999/XMLSchema">
	<SOAP-ENV:Body>
		<ns1:doubleAnIntegerResponse
		 xmlns:ns1="urn:MySoapServices"
		 SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
			<return xsi:type="xsd:int">246</return>
		</ns1:doubleAnIntegerResponse>
	</SOAP-ENV:Body>
  </SOAP-ENV:Envelope>

Notez que la plupart des packages SOAP que vous utiliserez prendront en charge les détails de syntaxe des messages SOAP pour vous, mais afin d'être capable de lire, de comprendre et de déboguer des dialogues SOAP, regardons ces messages point par point.

Le prologue XML contient seulement une déclaration XML <?xml version="1.0" encoding="UTF-8" ?> spécifiant la version de XML et l'encodage des caractères du message XML.

Le tag de l'Enveloppe SOAP <SOAP-ENV:Envelope ... >dans le message de requête spécifie tout d'abord que le style d'encodage de ce message SOAP suit le schéma défini dans http://schemas.xmlsoap.org/soap/encoding/. Notez que c'est optionnel et que ce sera présumé si ce n'est pas inclus comme c'est le cas dans le message de réponse. L'Enveloppe SOAP contient également des définitions de namespaces. Les identifiants des namespaces sont standards et la spécification SOAP demande à ce que ces namespaces soient définis correctement ou pas du tout (c-à-d qu'un message SOAP dans lequel manquent des définitions de namespaces est correct et peut être exploité mais un message contenant des définitions incorrectes, c-à-d non standards, est mauvais et refusé). Notez que la définition du namespace SOAP-ENC est absent du message de réponse mais cela ne signifie pas que le message est invalide. Pour plus de détails sur les namespaces XML, visitez http://www.w3.org/TR/REC-xml-names/.

Il n'y a pas de tag header (en-tête) SOAP dans cet exemple. Les en-têtes SOAP sont optionnelles et sont typiquement utilisées pour transmettre des données d'authentification ou de gestion de session. Il est important de se rappeler que l'authentification et la gestion de session sont en dehors du cadre du protocole SOAP, même si les designers de SOAP autorisent une certaine flexibilité dans la transmission de messages SOAP, de telle façon que les personnes qui les implémentent puissent inclure de telles informations.

Vient ensuite le tag SOAP Body (le corps) <SOAP-ENV:Body> qui n' a rien de remarquable en lui-même mais encapsule un unique tag de méthode qui porte le nom de la méthode elle-même <ns1:doubleAnInteger ... > (ou, le même nom suivi du mot "Response" dans le cas du message de réponse). Notez que le tag de la méthode reçoit typiquement le namespace correspondant au nom du service, dans notre cas urn:MySoapServices pour assurer l'unicité (un service web, qui peut contenir n'importe quel nombre de méthodes nommées différemment, a un nom de service unique à l'URL sur laquelle il est accessible - plus de détails peuvent être trouvés sur les URLs de service ainsi que les noms de services et de méthodes dans la section SOAP Côté Serveur ).

Le tag de méthode encapsule à son tour n'importe quel nombre de paramètres, tel que le tag <param1 ... > dans l' enveloppe de requête. Les noms des tags de paramètres peuvent être n'importe quoi, sont typiquement autogénérés et n'ont pas de namespace. Dans le message de réponse, il n'y a jamais qu'un seul tag de paramètre (représentant la valeur de retour de la méthode) et il est typiquement appelé <return>.

Des exemples plus complexes...

L' une des caractéristiques les plus puissantes du protocole SOAP est sa capacité à gérer des paramètres de tout niveau de complexité. Au fond, cela se réduit à la capacité de traiter des types primitifs (entier, chaîne de caractères etc...), tableaux et structures et toutes combinaisons de ceux-ci. Regardons à quoi ressemblent les dialogues SOAP pour des méthodes avec des types de paramètres et de retour complexes.

Ci-dessous se trouve le dialogue résultant de l'appel de la version initiale de getEmployeeDetails comme décrit dans la section d'introduction Qu'est-ce que SOAP? Dans cette version, le client envoie un entier et reçoit un tableau de chaînes de caractères (un tableau de chaînes de caractères à deux éléments contenant le nom de l'employé et le numéro de téléphone). Notez l'information de type contenue dans le tag <return> du message de réponse, à savoir xsi:type="ns2:Array" ns2:arrayType="xsd:string[2]", qui décrit la structure du tableau.
Signature de la Methode

  String[] getEmployeeDetails ( int employeeNumber );
Requête

  <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
  <SOAP-ENV:Envelope
   SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
   xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
   xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
   xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
   xmlns:xsd="http://www.w3.org/1999/XMLSchema">
	<SOAP-ENV:Body>
		<ns1:getEmployeeDetails
		 xmlns:ns1="urn:MySoapServices">
			<param1 xsi:type="xsd:int">1016577</param1>
		</ns1:getEmployeeDetails>
	</SOAP-ENV:Body>
  </SOAP-ENV:Envelope>
Réponse

  <?xml version="1.0" encoding="UTF-8" ?>
  <SOAP-ENV:Envelope
   xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
   xmlns:xsd="http://www.w3.org/1999/XMLSchema"
   xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
	<SOAP-ENV:Body>
		<ns1:getEmployeeDetailsResponse
		xmlns:ns1="urn:MySoapServices"
		SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
			<return
			xmlns:ns2="http://schemas.xmlsoap.org/soap/encoding/"
			xsi:type="ns2:Array"
			ns2:arrayType="xsd:string[2]">
				<item xsi:type="xsd:string">Bill Posters</item>
				<item xsi:type="xsd:string">+1-212-7370194</item>
			</return>
		</ns1:getEmployeeDetailsResponse>
	</SOAP-ENV:Body>
  </SOAP-ENV:Envelope>

Plus tard, nous avons rendu le service un peu plus complexe. Nous voulions fournir un set plus complet de numéros de contact valides sur une période pendant laquelle les employés vont et viennent en voyages d'affaires. Le dialogue résultant de cet appel à une version révisée de getEmployeeDetails se trouve ci-dessous. Le client envoie toujours un entier mais reçoit un type complexe. Notez l'emboîtement des données dans le message de réponse et sa corrélation avec les définitions de types.
Signature de la Methode

  EmployeeContactDetail getEmployeeDetails ( int employeeNumber );

  où le type complexe EmployeeContactDetail est défini comme suit:  

  EmployeeContactDetail {
       String employeeName;
       String phoneNumber;
       TemporaryPhoneNumber[] tempPhoneNumber;
  }

  et le sous-type complexe TemporaryPhoneNumber est défini comme suit:
  
  TemporaryPhoneNumber {
       int startDate; //julian date
       int endDate;   //julian date
       String phoneNumber;
  }
Requête

  <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
  <SOAP-ENV:Envelope
   SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
   xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
   xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
   xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
   xmlns:xsd="http://www.w3.org/1999/XMLSchema">
	<SOAP-ENV:Body>
		<ns1:getEmployeeDetails
		 xmlns:ns1="urn:MySoapServices">
			<param1 xsi:type="xsd:int">1016577</param1>
		</ns1:getEmployeeDetails>
	</SOAP-ENV:Body>
  </SOAP-ENV:Envelope>
Réponse

  <?xml version="1.0" encoding="UTF-8" ?>
  <SOAP-ENV:Envelope
   xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
   xmlns:xsd="http://www.w3.org/1999/XMLSchema"
   xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    <SOAP-ENV:Body>
        <ns1:getEmployeeDetailsResponse
         xmlns:ns1="urn:MySoapServices"
         SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
            <return xsi:type="ns1:EmployeeContactDetail">
                <employeeName xsi:type="xsd:string">Bill Posters</employeeName>
                <phoneNumber xsi:type="xsd:string">+1-212-7370194</phoneNumber>
                <tempPhoneNumber
                 xmlns:ns2="http://schemas.xmlsoap.org/soap/encoding/"
                 xsi:type="ns2:Array"
                 ns2:arrayType="ns1:TemporaryPhoneNumber[3]">
                    <item xsi:type="ns1:TemporaryPhoneNumber">
                        <startDate xsi:type="xsd:int">37060</startDate>
                        <endDate xsi:type="xsd:int">37064</endDate>
                        <phoneNumber xsi:type="xsd:string">+1-515-2887505</phoneNumber>
                    </item>
                    <item xsi:type="ns1:TemporaryPhoneNumber">
                        <startDate xsi:type="xsd:int">37074</startDate>
                        <endDate xsi:type="xsd:int">37078</endDate>
                        <phoneNumber xsi:type="xsd:string">+1-516-2890033</phoneNumber>
                    </item>
                    <item xsi:type="ns1:TemporaryPhoneNumber">
                        <startDate xsi:type="xsd:int">37088</startDate>
                        <endDate xsi:type="xsd:int">37092</endDate>
                        <phoneNumber xsi:type="xsd:string">+1-212-7376609</phoneNumber>
                    </item>
                </tempPhoneNumber>
            </return>
        </ns1:getEmployeeDetailsResponse>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Dans les sections précédentes "Les Bases de SOAP", nous avons appris ce qu'est SOAP et comment il peut être utilisé comme le protocole de message pour le Service Web. Dans cette section, nous avons regardé ce à quoi ressemblent les messages et, et ce à quoi ressemblent vraiment les dialogues lorsqu'un service web basé sur SOAP est consommé. Dans la section finale des Bases SOAP, nous jetterons un coup d'œil sur les différents éléments qui composent un système s'appuyant sur SOAP, ce que chacun d'entre eux fait et comment ils interagissent.

[ Nicholas Quaine ]

Suivant

Copyright © 2001-2007 Nicholas Quaine. Tout droit reservé.