+

Search Tips   |   Advanced Search

Example: Passing SOAP messages with attachments 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 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) using a multipart IME 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>

In this type of WSDL extension:


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 we 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);

We 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");
yInterface 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 the WSDL, we 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

The following scenarios are not supported:

The MIME headers from the incoming message are not preserved for referenced attachments. The outgoing message contains new MIME headers for Content-Type, Content-Id and Content-Transfer-Encoding created by WSIF.

  • Use complex types
  • Use WSIF to bind a JNDI reference to a web service
  • Linking a WSIF service to the underlying implementation of the service
  • Linking a WSIF service to a SOAP over HTTP service
  • Interacting with the Java EE container in WAS
  • Running WSIF as a client
  • Use WSIF to invoke web services
  • W3C SOAP essages with Attachments