Describe how to configure web service providers and clients to use message optimization.

[Note]

MTOM (Message Transmission and Optimization Mechanism) together with XOP (XML Binary Optimized Packaging) defines how an XML binary data such as xs:base64Binary or xs:hexBinary can be optimally transmitted over the wire.

XML type, such as xs:base64Binary is sent in lined inside the SOAP envelope. This gets quite in-efficient when the data size is more, for example a SOAP endpoint that exchanges images/songs etc. MTOM specifies how XOP packaging can be used to send the binary data optimally.

MTOM feature is disabled in JAX-WS by default. It can be enabled on the client and server. Once enabled all the XML binary data, XML elements of type xs:base64Binary and xs:hexBinary is optimally transmitted.

An schema element of type xs:bas64Binary or xs:hexBinary can be annotated by using attribute reference using xmime:expectedContentType. JAXB 2.0 specification defines xmime:expectedContentType to Java type mapping:

image/gif           java.awt.Image
image/jpg           java.awt.Image
text/plain          java.lang.String
text/xml            javax.xml.transform.Source
application/xml     javax.xml.transform.Source
multipart/*         javax.activation.DataHandler
all other types     javax.activation.DataHandler
					


<element name="image" type="base64Binary" />
					
					
is mapped to:
byte[]
					


<element name="image" type="base64Binary" 
    xmime:expectedContentTypes="image/jpeg" 
    xmlns:xmime="http://www.w3.org/2005/05/xmlmime"/>
					
					
is mapped to:
java.awt.Image
					

How to enable MTOM in JAX-WS 2.0

As defined by JAXB 2.0 specification xs:base64Binary and xs:hexBinary mapping to java is byte[]. JAXWS implementation has set a threshold of 1KB of byte[] size. This threshold can be modified using implementation specific property com.sun.xml.ws.developer.JAXWSProperties.MTOM_THRESHOLD_VALUE in the RequestContext on the client side and in the MessageContext on the server side.

If the byte[] that is being sent is less than this threshold (default is 1KB) then the binary data is base64 encoded by JAXB and in lined inside the SOAP Body otherwise the binary data is sent as attachment mime part in Multipart/Related package and XML infoset for the binary data is XOP encoded by JAXB - <xop:Include href=...> is used to reference the attachment. The XOP encoding and packaging is done as per described by the XOP packaging rules. The href is the the Content-ID of the attachment and is encoded as per CID URI scheme defined in RFC 2111. xmime:contentType attribute may appear on the element that includes binary data to indicate preferred media type as annotated on the corresponding schema.

What is MTOM

Perhaps the best way to understand the pros and cons of MTOM is to see an actual on-the-wire message. See an example below:


Content-Type: Multipart/Related; start-info="text/xml"; type="application/xop+xml"; boundary="----=_Part_0_1744155.1118953559416"
Content-Length: 3453
SOAPAction: ""

------=_Part_1_4558657.1118953559446
Content-Type: application/xop+xml; type="text/xml"; charset=utf-8

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
  <S:Body>
    <Detail xmlns="http://example.org/mtom/data">
      <image>
        <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:5aeaa450-17f0-4484-b845-a8480c363444@example.org" />
      </image>
    </Detail>
  </S:Body>
</S:Envelope>


------=_Part_1_4558657.1118953559446
Content-Type: image/jpeg
Content-ID: <5aeaa450-17f0-4484-b845-a8480c363444@example.org>


... binary data ...
					
					

The noteworthy points are:

  1. The binary attachment is packaged in a MIME multi-part message (the same mechanism used in e-mail to handle attachments).

  2. An xop:Include element is used to mark where the binary data is.

  3. The actual binary data is kept in a different MIME part.

MTOM is efficient, in the sense that it doesn't have the 33% size increase penalty that xs:base64Binary has. It is interoperable, in the sense that it is a W3C standard. However, MIME multipart incurs a small cost proportional to the number of attachments, so it is not suitable for a large number of tiny attachments.

Schema:


<element name="Detail" type="types:DetailType"/>
<complexType name="DetailType">
  <sequence>
    <element name="image" type="base64Binary" />
  </sequence>
</complexType>

					

JAX-WS and MTOM example

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 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.

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.

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.

JAX-WS MIME attribute:


<definitions ...>

  <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>
  ...
</definitions>  
					 
					 

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

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, 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.

JAX-WS still supports the Sw/A model. By default, JAX-WS maps a Sw/A attachment to a byte[] on the Java interface. To get the mapping you are used to in JAX-RPC, you can use the enableMIMEContent WSDL binding definition. Listing below shows the JAX-WS version of the Java interface.

Professional hosting     Belorussian informational portal         Free SCWCD 1.4 Study Guide     Free SCDJWS 1.4 Study Guide     SCDJWS 1.4 Quiz     Free IBM Certified Associate Developer Study Guide     IBM Test 000-287. Enterprise Application Development with IBM WebSphere Studio, V5.0 Study Guide     SCDJWS 5.0 Quiz