Information and example code for using the Web Services Invocation Framework (WSIF) SOAP provider to pass attachments within a MIME multipart/related message in such a way that the SOAP processing rules for a standard SOAP message are not changed. This includes how to write the Web Services Description Language (WSDL) extensions for SOAP attachments, and how to work with types and type mappings.
The W3C SOAP Messages with Attachments document describes a standard way to associate a SOAP message with one or more attachments in their native format (for example GIF or JPEG) by using a multipart MIME structure for transport. It defines specific use of the "Multipart/Related" MIME media type, and rules for the use of URI references to entities bundled within the MIME package. It thereby outlines a technique for carrying a SOAP 1.1 message within a MIME multipart/related message in such a way that the SOAP processing rules for a standard SOAP message are not changed.
WSIF supports passing attachments in a MIME message using the SOAP provider to link a WSIF service to a SOAP over HTTP service. The attachment is a javax.activation.DataHandler object. The mime:multipartRelated, mime:part and mime:content tags are used to describe the attachment in the WSDL.
The following example WSDL illustrates a simple operation that has one attachment called 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>
The following code fragment can invoke the service described by the example WSDL in Example: Writing the WSDL extensions for SOAP attachments:
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);
The associated type mapping in the DeploymentDescriptor.xml file depends upon your SOAP server. For example if you use Tomcat with SOAP 2.3, then the DeploymentDescriptor.xml file contains the following type mapping:
<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>
In this case, the backend service is invoked with the following signature:
public void MyOperation(DataHandler dh);
You can also use stubs to pass attachments into the Web Services Invocation Framework (WSIF):
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);
Attachments can also be returned from an operation, but only one attachment can be returned as the return parameter.
By default, attachments are passed into WSIF as DataHandler objects. If the part on the message that is the DataHandler object maps to a <mime:part> tag in the WSDL, then WSIF automatically maps the fully qualified name of the WSDL type to the DataHandler class and sets up that type mapping with the SOAP provider.
In your WSDL, you might have defined a schema for the attachment (for instance as a binary[] type). WSIF silently ignores this mapping and treats the attachment as a DataHandler object, unless you explicitly issue a mapType() method. WSIF lets the SOAP provider set the MIME content type based on the type of the DataHandler object, instead of the type attribute specified for the <mime:content> tag in the WSDL.