Skip to main content

Web services hints and tips: JAX-RPC versus JAX-WS, Part 5

Comparing attachment files: Sw/A and MTOM

Russell Butek (butek@us.ibm.com), Certified IT Specialist, IBM, Software Group
Russell Butek is an IBM SOA/Web services consultant. He has been one of the developers of IBM's WebSphere Web services engine. He has also been a member the JAX-RPC Java Specification Request (JSR) expert group. He was involved in the implementation of Apache's Axis SOAP engine, driving Axis 1.0 to comply with JAX-RPC.
Nicholas Gallardo (nlgallar@us.ibm.com), Advisory Software Engineer, IBM, Software Group
Nick Gallardo is an IBM software engineer working on the WebSphere platform. He has worked on various aspects of the Websphere Web services run time, with a concentration on the programming models. In addition, Nick is a member of the Apache Software Foundation and helped shape the support for JAX-WS within the Axis2 community.

Summary:  Java™ API for XML-based RPC (JAX-RPC) supports the SOAP with Attachments (Sw/A) specification, while Java API for XML Web Services (JAX-WS) supports Sw/A along with the new Message Transmission Optimization Mechanism (MTOM) specification. This fifth tip in this series compares these two attachment models by examining samples of Web Services Description Languages (WSDLs) and mapped Java interfaces.

View more content in this series

Date:  15 Nov 2007
Level:  Intermediate
Activity:  3614 views

Introduction

The attachment model for JAX-RPC is Sw/A. Since JAX-RPC was written, a new attachment model has come onto the scene: MTOM. JAX-WS provides Sw/A support just as JAX-RPC does, but adds support for MTOM. JAX-WS supports MTOM via the Java Architecture for XML Binding (JAXB) specification, which includes APIs for marshalling and unmarshalling both Sw/A and MTOM attachments. In this tip, you examine both models through examples. Note: This tip compares only the WSDLs and the Java programming models; comparing the wire-level messages is left as an exercise to the reader.


JAX-RPC and Sw/A example

Listing 1 shows the WSDL from an attachment tip written a few years ago (see Resources). Listing 2 shows the Java interface, which the JAX-RPC mapping produces from this WSDL.


Listing 1. JAX-RPC Sw/A WSDL
<definitions
        xmlns="http://schemas.xmlsoap.org/wsdl/"
        xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
        xmlns:tns="http://attachment.tip/"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
        targetNamespace="http://attachment.tip/">
  <types/>
  <message name="sendImage">
    <part name="image" type="xsd:base64Binary"/>
  </message>
  <message name="sendImageResponse"/>
  <message name="sendOctet">
    <part name="octet" type="xsd:base64Binary"/>
  </message>
  <message name="sendOctetResponse"/>
  <portType name="AttachmentTip">
    <operation name="sendImage">
      <input message="tns:sendImage"/>
      <output message="tns:sendImageResponse"/>
    </operation>
    <operation name="sendOctet">
      <input message="tns:sendOctet"/>
      <output message="tns:sendOctetResponse"/>
    </operation>
  </portType>
  <binding name="AttachmentBinding" type="tns:AttachmentTip">
    <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="sendImage">
      <soap:operation soapAction=""/>
      <input>
        <mime:multipartRelated>
          <mime:part>
            <soap:body parts="" namespace="http://attachment.tip/" use="literal"/>
          </mime:part>
          <mime:part>
            <mime:content part="image" type="image/jpeg"/>
          </mime:part>
        </mime:multipartRelated>
      </input>
      <output>
        <soap:body namespace="http://attachment.tip/" use="literal"/>
      </output>
    </operation>
    <operation name="sendOctet">
      <soap:operation soapAction=""/>
      <input>
        <mime:multipartRelated>
          <mime:part>
            <soap:body parts="" namespace="http://attachment.tip/" use="literal"/>
          </mime:part>
          <mime:part>
            <mime:content part="octet" type="application/octet-stream"/>
          </mime:part>
        </mime:multipartRelated>
      </input>
      <output>
        <soap:body namespace="http://attachment.tip/" use="literal"/>
      </output>
    </operation>
  </binding>
  <service name="AttachmentService">
    <port binding="tns:AttachmentBinding" name="AttachmentTip">
      <soap:address location="http://localhost:9080/SwAService/services/AttachmentTip"/>
    </port>
  </service>
  </definitions>


Listing 2. JAX-RPC Sw/A Java interface
package tip.attachment;

import java.awt.Image;
import java.rmi.Remote;
import java.rmi.RemoteException;

import javax.activation.DataHandler;

public interface AttachmentTip extends Remote {
    public void sendImage(Image image) throws RemoteException;
    public void sendOctet(DataHandler octet) throws RemoteException;
}

The Java interface mapping from the WSDL is fairly straightforward: The sendImage operation's image/jpeg part is mapped to a java.awt.Image parameter; the sendOctet operation's application/octet-stream is mapped to a javax.activation.DataHandler parameter. However, there's a cost to this mapping: The Multipurpose Internet Mail Extensions (MIME) type information isn't in the interface portion of the WSDL (the portType, message, and types sections). You must dip into the binding to find the MIME information. This is unfortunate because different bindings for the same WSDL interface could result in different types and, therefore, map to different Java interfaces. It would be better if there were a one-to-one mapping from WSDL interface to Java interface. If you have more than one binding, each simply maps to an implementation, all of which implements the same Java interface. With Sw/A, you can't do that; the mapping from WSDL to Java interfaces is not one to one.

A secondary issue with Sw/A is that it doesn't lend itself well to the industry convention of document/literal wrapped WSDL (you'll notice that the WSDL in Listing 1 is an rpc/literal WSDL). Adding Sw/A content to a document/literal wrapped message requires specifying additional message parts beyond the single operation wrapper.

Does MTOM fix these issues? Let's move on to the next section to find out.


JAX-WS and MTOM example

In Listing 3, we've modified the Sw/A WSDL from Listing 1 to produce an equivalent MTOM WSDL.


Listing 3. JAX-WS MTOM WSDL
<definitions
        xmlns="http://schemas.xmlsoap.org/wsdl/"
        xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
        xmlns:tns="http://attachment.tip/"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://attachment.tip/">
  <types/>
  <message name="sendImage">
    <part name="image" type="xsd:base64Binary"/>
  </message>
  <message name="sendImageResponse"/>
  <message name="sendOctet">
    <part name="octet" type="xsd:base64Binary"/>
  </message>
  <message name="sendOctetResponse"/>
  <portType name="AttachmentTip">
    <operation name="sendImage">
      <input message="tns:sendImage"/>
      <output message="tns:sendImageResponse"/>
    </operation>
    <operation name="sendOctet">
      <input message="tns:sendOctet"/>
      <output message="tns:sendOctetResponse"/>
    </operation>
  </portType>
  <binding name="AttachmentBinding" type="tns:AttachmentTip">
    <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="sendImage">
      <soap:operation soapAction=""/>
      <input>
        <soap:body namespace="http://attachment.tip/" use="literal"/>
      </input>
      <output>
        <soap:body namespace="http://attachment.tip/" use="literal"/>
      </output>
    </operation>
    <operation name="sendOctet">
      <soap:operation soapAction=""/>
      <input>
        <soap:body namespace="http://attachment.tip/" use="literal"/>
      </input>
      <output>
        <soap:body namespace="http://attachment.tip/" use="literal"/>
      </output>
    </operation>
  </binding>
  <service name="AttachmentService">
    <port binding="tns:AttachmentBinding" name="AttachmentTip">
      <soap:address location="http://localhost:9080/MTOMService/services/AttachmentTip"/>
    </port>
  </service>
</definitions>

The only real difference between the MTOM WSDL in Listing 3 and the Sw/A WSDL in Listing 1 is the binding. The MTOM binding contains no MIME information. In fact, there's no way to tell, from the WSDL, that you're dealing with attachments; the WSDL's binding looks like a normal binding.

Listing 4 shows the Java interface, which a JAX-WS mapping produces from this WSDL.


Listing 4. JAX-WS MTOM Java interface
package tip.attachment;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;

@WebService(name = "AttachmentTip", targetNamespace = "http://attachment.tip/")
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface AttachmentTip {


    @WebMethod
    public void sendImage(
        @WebParam(name = "image", partName = "image")
        byte[] image);

    @WebMethod
    public void sendOctet(
        @WebParam(name = "octet", partName = "octet")
        byte[] octet);

}

Because the WSDL is a normal-looking WSDL with no hint of attachments, you end up with a Java interface that reflects that as well. Given parts of type base64Binary (or hexBinary), JAX-WS maps those to parameters of type byte[]. With MTOM, the MIME-ness of the types has all been extracted from the WSDL with the burden placed on the client or server run time to format the content appropriately.


Comparison of Sw/A and MTOM

The JAX-RPC Sw/A section noted two drawbacks to Sw/A:

  • The MIME type info is in the WSDL binding, not the WSDL interface.
  • It's difficult to create a document/literal wrapped attachment WSDL.

Let's discuss the document/literal wrapped style first.

document/literal wrapped style and attachments

We left the MTOM WSDL in Listing 3 as rpc/literal WSDL for comparison purposes; but it's an easy matter to turn this WSDL into document/literal wrapped WSDL. Listing 5 in the next section shows the document/literal wrapped equivalent of the WSDL in Listing 3 (see Resources for more information about the differences between various WSDL styles).

MIME type info in the binding

Because the MTOM WSDL's binding doesn't have any MIME information, you don't have to dip into the binding to determine the part types. You have everything you need in the WSDL interface to generate the Java interface. However, as you can see by comparing the Java interfaces in Listing 2 and Listing 4, we've lost some information.

The interface portion of both WSDLs shows that the data type in the operations is base64Binary, which maps to byte[]. In the JAX-RPC Sw/A WSDL, however, you know from the binding that the part types are a MIME image and a MIME octet stream. In the JAX-WS MTOM WSDL, this information is lost. This may seem like a bad thing, but the positive spin is that this completely cleans up the interface. No matter what the binding, the interface is always the same. In fact, the implementors of the client and the server codebases shouldn't be bothered with the notion of whether the parameter is an attachment. That's merely a detail of the SOAP message, and the writers of the WSDL-to-Java mappings have tried their best to abstract the programmer away from the details of the SOAP message.

However, if you really want to know what the MIME type is—if you want to get back to the information you lost—JAX-WS provides support for an attribute that you can inject into an XML element: expectedContentTypes. This special attribute is highlighted in Listing 5. Listing 6 shows the corresponding Java interface. Ignoring the annotations, this Java interface is essentially the same as the interface in Listing 2.


Listing 5. JAX-WS MIME attribute
<definitions
        xmlns="http://schemas.xmlsoap.org/wsdl/"
        xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
        xmlns:tns="http://attachment.tip/"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://attachment.tip/">
  <types>
    <xsd:schema
            xmlns:tns="http://attachment.tip/"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="http://attachment.tip/">
      <xsd:element name="sendImage" type="tns:sendImage"/>
      <xsd:complexType name="sendImage">
        <xsd:sequence>
          <xsd:element
                  xmlns:ns1="http://www.w3.org/2005/05/xmlmime"ns1:expectedContentTypes="image/*"
                  name="image"
                  type="xsd:base64Binary"/>
        </xsd:sequence>
      </xsd:complexType>
      <xsd:element name="sendImageResponse" type="tns:sendImageResponse"/>
      <xsd:complexType name="sendImageResponse">
        <xsd:sequence/>
      </xsd:complexType>
      <xsd:element name="sendOctet" type="tns:sendOctet"/>
      <xsd:complexType name="sendOctet">
        <xsd:sequence>
          <xsd:element 
                 xmlns:ns1="http://www.w3.org/2005/05/xmlmime"ns1:expectedContentTypes="application/octet-stream"
                 name="octet"
                 type="xsd:base64Binary"/>
        </xsd:sequence>
      </xsd:complexType>
      <xsd:element name="sendOctetResponse" type="tns:sendOctetResponse"/>
      <xsd:complexType name="sendOctetResponse">
        <xsd:sequence/>
      </xsd:complexType>
    </xsd:schema>
  </types>
  <message name="sendImage">
    <part name="parameters" element="tns:sendImage"/>
  </message>
  <message name="sendImageResponse">
    <part name="parameters" element="tns:sendImageResponse"/>
  </message>
  <message name="sendOctet">
    <part name="parameters" element="tns:sendOctet"/>
  </message>
  <message name="sendOctetResponse">
    <part name="parameters" element="tns:sendOctetResponse"/>
  </message>
  <portType name="AttachmentTip">
    <operation name="sendImage">
      <input message="tns:sendImage"/>
      <output message="tns:sendImageResponse"/>
    </operation>
    <operation name="sendOctet">
      <input message="tns:sendOctet"/>
      <output message="tns:sendOctetResponse"/>
    </operation>
  </portType>
  <binding name="AttachmentBinding" type="tns:AttachmentTip">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="sendImage">
      <soap:operation soapAction=""/>
      <input>
        <soap:body use="literal"/>
      </input>
      <output>
        <soap:body use="literal"/>
      </output>
    </operation>
    <operation name="sendOctet">
      <soap:operation soapAction=""/>
      <input>
        <soap:body use="literal"/>
      </input>
      <output>
        <soap:body use="literal"/>
      </output>
    </operation>
  </binding>
  <service name="AttachmentService">
    <port binding="tns:AttachmentBinding" name="AttachmentTip">
      <soap:address location="http://localhost:9080/MTOMService/services/AttachmentTip"/>
    </port>
  </service>
</definitions>

Notice that this new attribute is wholly contained within the WSDL interface. It's not in the binding, so all of the type information is where you want it.


Listing 6. JAX-WS Java interface mapped from the MIME attribute
package tip.attachment;

import java.awt.Image;
import javax.activation.DataHandler;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;

@WebService(name = "AttachmentTip", targetNamespace = "http://attachment.tip/")
public interface AttachmentTip {

    @WebMethod
    @RequestWrapper(localName = "sendImage", 
            targetNamespace = "http://attachment.tip/", 
            className = "tip.attachment.SendImage")
    @ResponseWrapper(localName = "sendImageResponse", 
            targetNamespace = "http://attachment.tip/", 
            className = "tip.attachment.SendImageResponse")
    public void sendImage(
        @WebParam(name = "image", targetNamespace = "")
        Image image);

    @WebMethod
    @RequestWrapper(localName = "sendOctet", 
            targetNamespace = "http://attachment.tip/", 
            className = "tip.attachment.SendOctet")
    @ResponseWrapper(localName = "sendOctetResponse", 
            targetNamespace = "http://attachment.tip/", 
            className = "tip.attachment.SendOctetResponse")
    public void sendOctet(
        @WebParam(name = "octet", targetNamespace = "")
        DataHandler octet);
}

As mentioned earlier, JAX-WS relies on JAXB to handle the data binding for most of its Web services content. The mapping for the expectedContentTypes element is defined in Appendix H of the JAXB 2.0 specification (see Resources). The JAXB 2.0 mappings are similar to the JAX-RPC mappings. Compare these mappings in Table 1.


Table 1. MIME type to Java type mappings
MIME typeJAX-RPC mappingJAX-WS/JAXB mapping
image/gifjava.awt.Imagejava.awt.Image
image/jpgjava.awt.Imagejava.awt.Image
text/plainjava.lang.Stringjavax.xml.transform.Source
text/xmljavax.xml.transform.Sourcejavax.xml.transform.Source
application/xmljavax.xml.transform.Sourcejavax.xml.transform.Source
multipart/*javax.mail.internet.MimeMultipartjavax.activation.DataHandler
all other typesjavax.activation.DataHandlerjavax.activation.DataHandler

enabling/disabling attachment support

One of the of additional benefits of MTOM is the fact that you can turn it on or off. In the case of Sw/A, if one side or the other doesn't support sending Sw/A attachments, then the contract defined by the WSDL cannot be honored. On the other hand, if you have an MTOM WSDL such as that in listing 3 or 5, a client could choose to send data as an MTOM attachment or inline in the SOAP message. No matter what the client chooses, it can still interact with the Web service. MTOM is just an optimization of sending content, not a mandate like Sw/A.


Sw/A and JAX-WS

JAX-WS still supports the Sw/A model. By default, JAX-WS maps a Sw/A attachment to a byte[] on the Java interface, like the sample in Listing 4. To get the mapping you are used to in JAX-RPC, you can use the enableMIMEContent WSDL binding definition (see section 8.7.5 of the JAX-WS specification for more details). Listing 7 shows the JAX-WS version of the Java interface equivalent to the JAX-RPC version of the interface in listing 2.


Listing 7. JAX-WS Java interface with Sw/A attachments mapped from the mime:content
package tip.attachment;

import java.awt.Image;
import javax.activation.DataHandler;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;

@WebService(name = "AttachmentTip", targetNamespace = "http://attachment.tip/")
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface AttachmentTip {


    @WebMethod
    public void sendImage(
        @WebParam(name = "image", partName = "image")
        Image image);

    @WebMethod
    public void sendOctet(
        @WebParam(name = "octet", partName = "octet")
        DataHandler octet);

}


Summary

JAX-RPC supports the Sw/A model. JAX-WS supports Sw/A as well, but it has also stepped up to the new MTOM model. MTOM is an improvement upon Sw/A in a number of ways:

  • Everything necessary to create a Java interface is now available in the WSDL interface.
  • MTOM is usable in a document/literal wrapped WSDL.
  • MTOM allows optimization to attachments, but it doesn't force attachments like Sw/A does.

Resources

Learn

Get products and technologies

  • Innovate your next development project with IBM trial software, available for download or on DVD.

Discuss

About the authors

Russell Butek is an IBM SOA/Web services consultant. He has been one of the developers of IBM's WebSphere Web services engine. He has also been a member the JAX-RPC Java Specification Request (JSR) expert group. He was involved in the implementation of Apache's Axis SOAP engine, driving Axis 1.0 to comply with JAX-RPC.

Nick Gallardo is an IBM software engineer working on the WebSphere platform. He has worked on various aspects of the Websphere Web services run time, with a concentration on the programming models. In addition, Nick is a member of the Apache Software Foundation and helped shape the support for JAX-WS within the Axis2 community.

Comments (Undergoing maintenance)



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=SOA and Web services
ArticleID=269336
ArticleTitle=Web services hints and tips: JAX-RPC versus JAX-WS, Part 5
publish-date=11152007
author1-email=butek@us.ibm.com
author1-email-cc=flanders@us.ibm.com
author2-email=nlgallar@us.ibm.com
author2-email-cc=flanders@us.ibm.com

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Rate a product. Write a review.

Special offers