Beispiel: SOAP-Nachrichten mit Anhängen über WSIF übergeben
Dieser Artikel enthält Informationen und Beispielcode zur Verwendung des WSIF-SOAP-Providers. Mit diesem Provider können Anhänge in einer MIME-Multipart/Related-Nachricht so übergeben werden, dass sich die SOAP-Verarbeitungsregeln für eine SOAP-Standardnachricht nicht ändern. Außerdem wird erläutert, wie WSDL-Erweiterungen (Web Services Description Language) für SOAP-Anhänge geschrieben werden und wie mit Typen und Typzuordnungen gearbeitet wird.
Das Dokument "W3C SOAP Messages with Attachments" beschreibt eine Standardmethode für die Zuordnung einer SOAP-Nachricht mit einem oder mehreren Anhängen im nativen Format (z. B. GIF oder JPEG) unter Verwendung einer mehrteiligen MIME-Struktur für den Transport. Es definiert die spezielle Verwendung des MIME-Typs "Multipart/Related" und die Regeln für die Verwendung von URI-Referenzen auf Entitäten, die im MIME-Paket enthalten sind. Das Dokument umreißt eine Technik für eine Nachricht gemäß SOAP 1.1, die so innerhalb einer Multipart/Related-MIME-Nachricht transportiert werden soll, dass die SOAP-Verarbeitungsregeln für eine Standard-SOAP-Nachricht sich nicht verändern.
WSIF unterstützt die Übergabe von Anhängen einer MIME-Nachricht mit dem SOAP-Provider. Dieser Anhang ist ein javax.activation.DataHandler-Objekt. Die Tags mime:multipartRelated, mime:part und mime:content beschreiben den Anhang in der WSDL.
Beispiel: WSDL-Erweiterungen für SOAP-Anhänge schreiben
Die folgende Beispiel-WSDL veranschaulicht eine einfache Operation mit einem Anhang 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>
- Die Eingabenachricht der Operation (in diesem Beispiel MyOperation muss ein Attribut part (in diesem Beispiel attch) enthalten. Für MyOperation kann es weitere Eingabeabschnitte geben, die keine Anhänge sind.
- Die Bindungseingabe muss entweder ein Tag <soap:body> oder ein Tag <mime:multipartRelated> enthalten. Beide Tags zusammen sind nicht zulässig.
- Für MIME-Nachrichten muss das Tag <soap:body> im Tag <mime:part> enthalten sein. Es darf nur ein Tag <mime:part>, das ein Tag <soap:body> enthält, in der Bindungseingabe enthalten sein. Dieses Tag darf kein Tag <mime:content> enthalten, weil der Inhaltstyp text/xml für den Tag <soap:body> angenommen wird.
- Eine MIME-Nachricht kann mehrere Anhänge enthalten, die jeweils durch ein Tag <mime:part> beschrieben werden.
- Jedes Tag <mime:part> ohne ein Tag <soap:body> enthält ein Tag <mime:content>, das den Anhang beschreibt. Das Attribut type innerhalb des Tag <mime:content> wird von WSIF (Web Services Invocation Framework) nicht überprüft oder verwendet. Es soll der Anwendung, die das WSIF nutzt, eine Information über den Inhalt der Anlage geben. Mehrere Tags <mime:content> innerhalb eines Tag <mime:part> bedeuten, dass der Back-End-Service nur einen Anhang mit einem der von den Tags <mime:content> innerhalb des Tag <mime:part> angegebenen Typen erwartet.
- Das (optionale) Attribut parts="..." innerhalb des Tag <soap:body> sollte die Namen aller MIME-Abschnitte sowie die Namen aller SOAP-Abschnitte in der Nachricht enthalten.
Beispiel: Mit WSIF SOAP-Anhänge übergeben
Das folgende Codefragment kann den Service, der von der Beispiel-WSDL im Artikel Beispiel: WSDL-Erweiterungen für SOAP-Anhänge schreiben beschrieben wird, aufrufen:
import javax.activation.DataHandler;
. . .
DataHandler dh = new DataHandler(new FileDataSource("meinBild.jpg"));
WSIFServiceFactory factory = WSIFServiceFactory.newInstance();
WSIFService service = factory.getService("meine.wsdl",null,null,"http://meinNamespace","abc");
WSIFOperation op = service.getPort().createOperation("MeineOperation");
WSIFMessage in = op.createInputMessage();
in.setObjectPart("attch",dh);
op.executeInputOnlyOperation(in);
Die zugehörige Typzuordnung in der Datei DeploymentDescriptor.xml richtet sich nach Ihrem SOAP-Server. Wenn Sie beispielsweise Tomcat mit SOAP 2.3 verwenden, enthält die Datei DeploymentDescriptor.xml die folgende Typzuordnung:
<isd:mappings>
<isd:map encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:x="http://meinNamespace"
qname="x:datahandler"
javaType="javax.activation.DataHandler"
java2XMLClassName="org.apache.soap.encoding.soapenc.MimePartSerializer"
xml2JavaClassName="org.apache.soap.encoding.soapenc.MimePartSerializer" />
</isd:mappings>
In diesem Fall wird der Back-End-Service mit der folgenden Signatur aufgerufen:
public void MeineOperation(DataHandler dh);
Sie können Anhänge auch mit Stubs an das Web Services Invocation Framework (WSIF) übergeben:
DataHandler dh = new DataHandler(new FileDataSource("meinBild.jpg"));
WSIFServiceFactory factory = WSIFServiceFactory.newInstance();
WSIFService service = factory.getService("meine.wsdl",null,null,"http://meinNamespace","abc");
MeinInterface stub = (MeinInterface)service.getStub(MeinInterface.class);
stub.MeineOperation(dh);
Es können auch Anhänge von einer Operation zurückgegeben werden. Es kann jedoch nur jeweils einen Anhang als Rückgabeparameter zurückgegeben werden.
SOAP-Anhänge - Mit Typen und Typzuordnungen arbeiten
Anhänge werden standardmäßig als DataHandler-Objekte an WSIF (Web Services Invocation Framework) übergeben. Wenn das DataHandler-Objekt der Nachricht in der WSDL einem Tag <mime:part> zugeordnet ist, ordnet das WSIF der Klasse DataHandler automatisch den vollständig qualifizierten Namen des WSDL-Typs zu und konfiguriert diese Typzuordnung mit dem SOAP-Provider.
Möglicherweise haben Sie in Ihrer WSDL ein Schema für den Anhang definiert (z. B. vom Typ binary[]). WSIF ignoriert diese Zuordnung und behandelt den Anhang als DataHandler-Objekt, bis Sie explizit eine Methode mapType() abgesetzt haben. WSIF lässt den SOAP-Provider den MIME-Inhaltstyp ausgehend vom Typ des DataHandler-Objekts und nicht ausgehend von dem in der WSDL angegebenen Attribut type für das Tag <mime:content> festlegen.
SOAP-Anhänge - Nicht unterstützte Szenarien
- Verwendung von DIME
- Übergabe von javax.xml.transform.Source und javax.mail.internet.MimeMultipart.
- Verwendung des WSDL-Tag mime:mimeXml.
- Verschachtelung von mime:multipartRelated innerhalb von mime:part.
- Verwendung von Typen, die eine Erweiterung zu DataHandler, Image usw. darstellen.
- Verwendung von Typen, die DataHandler, Image usw. enthalten.
- Verwendung von Feldgruppen oder Vektoren mit DataHandlers, Images etc.
- Verwendung mehrerer Ein-/Ausgabeanhänge oder Ausgabeanhänge.