Example: Passing SOAP messages with attachments by using WSIF
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.
Example: Writing the WSDL extensions for SOAP attachments
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>
- There must be a
partattribute (in this exampleattch) on the input message for the operation (in this exampleMyOperation). There can be other input parts toMyOperationthat are not attachments. - In the binding input there must either be a
<soap:body>tag or a<mime:multipartRelated>tag, but not both. - For MIME messages, the
<soap:body>tag is inside a<mime:part>tag. There must only be one<mime:part>tag that contains a<soap:body>tag in the binding input and that must not contain a<mime:content>tag as well, because a content type oftext/xmlis assumed for the<soap:body>tag. - There can be multiple attachments in a MIME message, each described
by a
<mime:part>tag. - Each
<mime:part>tag that does not contain a<soap:body>tag contains a<mime:content>tag that describes the attachment itself. Thetypeattribute inside the<mime:content>tag is not checked or used by the Web Services Invocation Framework (WSIF). It is there to suggest to the application that uses WSIF what the attachment contains. Multiple<mime:content>tags inside a single<mime:part>tag means that the backend service expects a single attachment with a type specified by one of the<mime:content>tags inside that<mime:part>tag. - The
parts="..."attribute (optional) inside the<soap:body>tag is assumed to contain the names of all the MIME parts as well as the names of all the SOAP parts in the message.
Example: Using WSIF to pass SOAP attachments
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.
SOAP attachments - Working with types and type mappings
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.
SOAP attachments - scenarios that are not supported
- Using DIME.
- Passing in
javax.xml.transform.Sourceandjavax.mail.internet.MimeMultipart. - Using the mime:mimeXml WSDL tag.
- Nesting a mime:multipartRelated tag inside a mime:part tag.
- Using types that extend
DataHandler,Image, and so on. - Using types that contain
DataHandler,Image, and soon. - Using Arrays or Vectors of
DataHandlers,Images, and so on. - Using multiple in/out or output attachments.