Exemple : Transmission des messages SOAP avec pièces jointes à l'aide de WSIF
Des informations et un code d'exemples sont destinés pour utilisation du fournisseur SOAP de WSIF (Web Services Invocation Framework) pour transmettre des pièces jointes à l'intérieur d'un message MIME de type Multipart/Related de sorte à conserver les règles de traitement SOAP d'un message SOAP standard. Cela inclut la manière d'écrire les extensions WSDL pour les pièces jointes SOAP, ainsi que la manière de travailler avec les types et les mappages de types.
Le document "Messages SOAP avec pièces jointes" du consortium World Wide Web (W3C) décrit la façon standard d'associer un message SOAP à une ou plusieurs pièces jointes en format natif (par exemple, GIF ou JPEG) par l'utilisation d'une structure MIME multipartie pour le transport. Il définit l'utilisation spécifique du type de support MIME "Multipart/Related", ainsi que les règles d'utilisation des références URI à des entités regroupées dans le package MIME. Il décrit ainsi une technique permettant de véhiculer un message SOAP 1.1 à l'intérieur d'un message MIME de type Multipart/Related de telle façon que les règles de traitement SOAP d'un message SOAP standard ne soient pas modifiées.
L'architecture WSIF prend en charge la transmission des pièces jointes dans un message MIME à l'aide du fournisseur SOAP pour lier un service WSIF à un service SOAP par HTTP. La pièce jointe est un élément javax.activation.DataHandler. Les balises mime:multipartRelated, mime:part et mime:content sont utilisées pour décrire la pièce jointe dans le fichier WSDL.
Exemple : Ecriture d'extensions WSDL pour pièces jointes SOAP
L'exemple de document WSDL suivant illustre une opération simple comportant une pièce jointe nommée attch :
<binding name="MyBinding" type="tns:abc" >
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="MyOperation">
<soap:operation soapAction=""/>
<input>
<mime:multipartRelated>
<mime:part>
<soap:body use="encoded" namespace="http://mynamespace"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding"/>
</mime:part>
<mime:part>
<mime:content part="attch" type="text/html"/>
</mime:part>
</mime:multipartRelated>
</input>
</operation>
</binding>
- Le message d'entrée doit contenir un attribut part (dans cet exemple, attch) pour l'opération (dans cet exemple, MyOperation). Il peut exister d'autres éléments d'entrée de MyOperation qui ne sont pas des pièces jointes.
- L'entrée de la liaison doit contenir une balise <soap:body> ou <mime:multipartRelated>, mais pas les deux.
- Pour les messages MIME, la balise <soap:body> est contenue dans une balise <mime:part>. Une seule balise <mime:part> doit contenir une balise <soap:body> dans l'entrée de liaison mais elle ne doit pas contenir de balise <mime:content> car un type de contenu de text/xml est spécifié par défaut pour la balise <soap:body>.
- Un message MIME peut contenir plusieurs pièces jointes ; chacune étant décrite par une balise <mime:part>.
- Chaque balise <mime:part> qui ne contient pas de balise <soap:body> contient une balise <mime:content> décrivant la pièce jointe elle-même. L'attribut type contenu dans la balise <mime:content> n'est pas contrôlé ou utilisé par Web Services Invocation Framework (WSIF). Il est là pour suggérer le contenu de la pièce jointe à l'application qui utilise WSIF. Plusieurs balises <mime:content> contenues dans une seule balise <mime:part> signifient que le service dorsal attend une seule pièce jointe dont le type est spécifié par l'une des balises <mime:content> à l'intérieur de cette balise <mime:part>.
- L'attribut parts="..." (facultatif) contenu dans la balise <soap:body> est supposé contenir les noms de toutes les parties MIME ainsi que les noms de toutes les parties SOAP du message.
Exemple : Utilisation de WSIF pour la transmission de pièces jointes SOAP
Le fragment de code suivant peut appeler le service décrit par l'exemple de fichier WSDL dans Exemple : Ecriture d'extensions WSDL pour pièces jointes SOAP :
import javax.activation.DataHandler;
. . .
DataHandler dh = new DataHandler(new FileDataSource("myimage.jpg"));
WSIFServiceFactory factory = WSIFServiceFactory.newInstance();
WSIFService service = factory.getService("my.wsdl",null,null,"http://mynamespace","abc");
WSIFOperation op = service.getPort().createOperation("MyOperation");
WSIFMessage in = op.createInputMessage();
in.setObjectPart("attch",dh);
op.executeInputOnlyOperation(in);
Le mappage de types associés défini dans le fichier DeploymentDescriptor.xml dépend du serveur SOAP. Par exemple, si vous utilisez Tomcat avec SOAP 2.3, le fichier DeploymentDescriptor.xml contient le mappage de types suivant :
<isd:mappings>
<isd:map encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:x="http://mynamespace"
qname="x:datahandler"
javaType="javax.activation.DataHandler"
java2XMLClassName="org.apache.soap.encoding.soapenc.MimePartSerializer"
xml2JavaClassName="org.apache.soap.encoding.soapenc.MimePartSerializer" />
</isd:mappings>
Dans ce cas, le service dorsal est appelé avec la signature suivante :
public void MyOperation(DataHandler dh);
Vous pouvez aussi utiliser des raccords pour transmettre les pièces jointes à la structure WSIF (Web Services Invocation Framework) :
DataHandler dh = new DataHandler(new FileDataSource("myimage.jpg"));
WSIFServiceFactory factory = WSIFServiceFactory.newInstance();
WSIFService service = factory.getService("my.wsdl",null,null,"http://mynamespace","abc");
MyInterface stub = (MyInterface)service.getStub(MyInterface.class);
stub.MyOperation(dh);
Les pièces jointes peuvent également être renvoyées à partir d'une opération, mais une seule pièce jointe peut être renvoyée en tant que paramètre de retour.
Pièces jointes des messages SOAP - Utilisation des types et mappages des types
Par défaut, les pièces jointes sont transmises à la structure WISF sous la forme d'objets DataHandler. Si la partie du message constituant l'objet DataHandler mappe une balise <mime:part> dans la WSDL, WSIF mappe alors automatiquement le nom complet du type WSDL à la classe DataHandler et définit le mappage de ce type avec le fournisseur SOAP.
Dans votre fichier WSDL, il est possible que vous ayez défini un schéma pour la pièce jointe (par exemple, sous la forme du type binary[]). WSIF ignore automatiquement ce mappage et traite la pièce jointe comme un objet DataHandler, à moins que vous ayez explicitement émis une méthode mapType(). WSIF permet au fournisseur SOAP de définir le type de contenu MIME en fonction du type d'objet DataHandler, au lieu de l'attribut type spécifié pour la balise <mime:content> dans le code WSDL.
Pièces jointes des messages SOAP - Scénarios qui ne sont pas pris en charge
- Utilisation de DIME.
- Transmission des éléments javax.xml.transform.Source et javax.mail.internet.MimeMultipart.
- Utilisation de la balise WSDL mime:mimeXml.
- Imbrication de mime:multipartRelated dans mime:part.
- Utilisation de types qui étendent DataHandler, Image, etc.
- Utilisation de types contenant DataHandler, Image, etc.
- Utilisation d'Arrays ou de Vectors de DataHandlers, Images, etc.
- Utilisation de plusieurs pièces jointes d'entrée/sortie ou de sortie.