Version 2

    Working with Attachments


    Part of the SAAJ-1.2 specification is how to add MIME attachments to

    to a SOAP message. The following MIME types are supported


    MIME Type

    Java Type














    The SOAP message will be transported as a MIME multipart message with the SOAP envelope being the first MIME part.





    Part of the JBoss webservice testsuite is a service endpoint interface that exposes six methods that deal with attachements. There is no need to have an java.lang.Object parameter that takes the MIME part, you might as well

    use the propper target type.


       public interface Attachment extends Remote
          /** Service endpoint method for image/gif
          String sendMimeImageGIF(String message, Object mimepart) throws RemoteException;


    The WSDL that defines the service uses elements from the mime namespace xmlns:mime=''. Also note that the actual message part

    that takes the attachment part use xsd:hexBinary.

    This is because we use Object for the mimepart parameter in the SEI.




    Here is a sample WSDL


       <definitions ... xmlns:mime="">
        <message name="Attachment_sendMimeImageGIF">
          <part name="message" type="xsd:string"></part>
          <part name="mimepart" type="xsd:hexBinary"></part>
        <message name="Attachment_sendMimeImageGIFResponse">
          <part name="response" type="xsd:string"></part>
        <portType name="Attachment">
          <operation name="sendMimeImageGIF">
            <input message="tns:Attachment_sendMimeImageGIF"/>
            <output message="tns:Attachment_sendMimeImageGIFResponse"></output>
        <binding name="AttachmentBinding" type="tns:Attachment">
          <soap:binding transport="" style="rpc"></soap:binding>
          <operation name="sendMimeImageGIF">
            <soap:operation soapAction=""></soap:operation>
                  <soap:body part="message" use="literal" namespace="http://org.jboss.webservice/attachment"></soap:body>
                  <mime:content part="mimepart" type="image/gif"></mime:content>
              <soap:body use="literal" namespace="http://org.jboss.webservice/attachment"></soap:body>
        <service name="Attachment">
          <port name="AttachmentPort" binding="tns:AttachmentBinding">
            <soap:address location="REPLACE_WITH_ACTUAL_URL"></soap:address>


    You endpoint bean may access the attachment parts using the standard SAAJ API.


          ServletEndpointContext context = (ServletEndpointContext)ctxWhichIsSetIn_ServiceLifecycle_init;
          SOAPMessageContext msgContext = (SOAPMessageContext)context.getMessageContext();
          SOAPMessage soapMessage = msgContext.getMessage();
          Iterator attachments = soapMessage.getAttachments();
          if (attachments.hasNext())
             AttachmentPart ap = (AttachmentPart);
             String contentType = ap.getContentType();
             if (expContentType.equals("multipart/*"))
                MimeMultipart mmp = (MimeMultipart)ap.getContent();
                int mmpCount = mmp.getCount();
                for (int i = 0; i < mmpCount; i++)
                   BodyPart bp = mmp.getBodyPart(i);
                   String bpct = bp.getContentType();
                   Object bpc = bp.getContent();
             else if (expContentType.equals("image/gif"))
                Image image = (Image)ap.getContent();


    Sending an Attachment from a DII client


    To send an image, we can use the standard DII API and make use of the Java activation framework.

    From the JavaDoc for DataHandler:


    +The DataHandler class provides a consistent interface to data available in many different sources and formats.

    It manages simple stream to string conversions and related operations using DataContentHandlers.+


          ServiceFactory factory = ServiceFactory.newInstance();
          Service service = factory.createService(SERVICE_NAME);
          Call call = service.createCall(PORT_NAME, new QName(NS_URI, rpcMethodName));
          call.addParameter("message", Constants.XSD_STRING, ParameterMode.IN);
          call.addParameter("mimepart", Constants.MIME_IMAGE, ParameterMode.IN);
          call.setTargetEndpointAddress("http://" + getServerHost() + ":8080/ws4ee-attachment");
          URL url = new File("resources/webservice/attachment/attach.gif").toURL();
          String message = "Some text message";
          String value = (String)call.invoke(new Object[]{message, new DataHandler(url)});


    You can also build the SOAP multipart message manually using the SAAJ API, which we will see next.


    Building a SOAP multipart message using SAAJ


    Using the SAAJ API directly, you can also construct a MIME multipart message and send it on the wire without using

    an JAX-RPC client.


          MessageFactory mf = MessageFactory.newInstance();
          // Create a soap message from the message factory.
          SOAPMessage msg = mf.createMessage();
          // Message creation takes care of creating the SOAPPart
          // a required part of the message as per the SOAP 1.1 spec.
          SOAPPart sp = msg.getSOAPPart();
          // Retrieve the envelope from the soap part to start building the soap message.
          SOAPEnvelope envelope = sp.getEnvelope();
          // Create a soap body from the envelope.
          SOAPBody bdy = envelope.getBody();
          // Add a soap body element
          SOAPBodyElement sbe = bdy.addBodyElement(envelope.createName(rpcMethodName, NS_PREFIX, NS_URI));
          // Add a some child elements
          sbe.addChildElement(envelope.createName("message")).addTextNode("Some text message");
          sbe.addChildElement(envelope.createName("mimepart")).addAttribute(envelope.createName("href"), CID_MIMEPART);
          AttachmentPart ap = msg.createAttachmentPart(new DataHandler(url));
          // Add the attachments to the message.
          SOAPConnectionFactory conFactory = SOAPConnectionFactory.newInstance();
          SOAPConnection con = conFactory.createConnection();
          SOAPMessage resMessage =, new URL("http://" + getServerHost() + ":8080/ws4ee-attachment"));


    Most conveniently, you might want to lookup the preconfigured JAX-RPC Service from JNDI and use it directly with

    Java method call semantics.


    Using a WS4EE client


    There is no special propriatary attachment handling needed. All plain vanilla WS4EE.


          InitialContext iniCtx = getInitialContext();
          Service service = (Service)iniCtx.lookup("java:comp/env/service/AttachmentService");
          Attachment port = (Attachment)service.getPort(Attachment.class);
          URL url = new File("resources/webservice/attachment/attach.gif").toURL();
          String value = port.sendMimeImageGIF("Some text message", new DataHandler(url));


    Running the Attachment testcases


    Use the source distribution or checkout from CVS, then build and run jboss


       cvs co -r Branch_4_0 jboss-4.x
       cd jboss-4.x


    Now build the testsuite and run one of the attachment testcase


       cd testsuite
       ant -Dtest=org.jboss.test.webservice.attachment.AttachmentProxyTestCase one-test
       Buildfile: build.xml
       Overriding previous definition of reference to xdoclet.task.classpath
        [junit] Running org.jboss.test.webservice.attachment.AttachmentProxyTestCase
        [junit] Tests run: 7, Failures: 0, Errors: 0, Time elapsed: 10.25 sec