6.2. Binary Attachments (MTOM)

6.2.1. MTOM

MTOM (and XOP) allows you to send and receive binary attachments (such as files and images) efficiently and in an interoperable manner.

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

Sample MTOM message

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.

The schema that describes the above message is below. The MTOM spec is designed to work below the XML infoset level, so the schema describes the image as being of type xs:base64Binary, even though it can be attached as seen above. When using MTOM, any base64Binary can be attached or inlined.

Schema

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

6.2.1.2. xmime:expectedContentType to Java type mapping

Schema elements of type xs:base64Binary or xs:hexBinary can be annotated by using the xmime:expectedContentType attribute to indicate the type of binary that is expected. wsimport recognizes this annotation and will map the binary data to its proper Java representation instead. The table below is taken from JAXB spec Table 9-1, which shows the mapping rules:

MIME Type Java Type
image/* java.awt.Image
text/plain java.lang.String
application/xml, text/xml javax.xml.transform.Source
(others) javax.activation.DataHandler

6.2.1.3. xmime:contentType attribute

The schema can further use the xmime:contentType attribute to designate the actual content type of the binary data used in the message. (In contrast, xmime:expectedContentTypes specifies what are allowed. This combination allows you to say "image/* is expected but this message contains image/jpeg".)

This attribute can be used with elements whose content is either xs:base64Binary or xs:hexBinary. Consider the following example:

Using xmime:contentType

<element name="TestMtomXmimeContentType" type="types:PictureType"/>

<complexType name="PictureType">
  <simpleContent>
    <restriction base="xmime:base64Binary">
      <attribute ref="xmime:contentType" use="required" />
    </restriction>
  </simpleContent>
</complexType>

Here xmime:base64Binary is defined by Describing Media Content of Binary Data in XML. The following code shows how your program can set the MIME type to the generated beans:

Setting content type

PictureType req = new PictureType();
req.setValue(name.getBytes());
req.setContentType("application/xml");

On the wire this is how it looks:

SOAP Message that uses xmime:contentType

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:ns1="http://example.org/mtom/data"
  xmlns:ns2="http://www.w3.org/2005/05/xmlmime">
  <S:Body>
    <ns1:TestMtomXmimeContentTypeResponse ns2:contentType="application/xml">
      <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include"
                   href="cid:193ed174-d313-4325-8eed-16cc25595e4e@example.org"/>
    </ns1:TestMtomXmimeContentTypeResponse>
  </S:Body>
</S:Envelope>

6.2.2. Enabling MTOM on server

There are several ways to enable MTOM.

  1. By using the @MTOM annotation on SEI. This is convenience and preferable for developers.
    Annotating SEI with @MTOM

    @javax.xml.ws.soap.MTOM
    @WebService
    public class HelloImpl implements Hello {
        ....
    }
  2. By using the enable-mtom attribute in the sun-jaxws.xml configuration file. This allows the MTOM setting to be changed at deployment time.
    Enabling MTOM in sun-jaxws.xml

    <endpoints xmlns='http://java.sun.com/xml/ns/jax-ws/ri/runtime' version='2.0'>
      <endpoint name="Mtom" implementation="mtom.server.HelloImpl"
        url-pattern="/hello"
        enable-mtom="true"/>
    </endpoints>
  3. If you are using JAX-WS RI via Spring, you can also enable MTOM from the bean definition file. See the JAX-WS spring extension for more.

6.2.3. Enabling MTOM on client

There are several ways to enable MTOM.

  1. By doing nothing. If the server WSDL advertises that it supports MTOM, the MTOM support in the client will be automatically enabled. This is the preferable way.
  2. By passing MTOMFeature as WebServiceFeature parameter while creating a proxy or a Dispatch. See the example below:
    Passing MTOMFeature

    Hello port = new HelloService().getHelloPort(new MTOMFeature());
    Dispatch d = new HelloService().createDispatch(....,new MTOMFeature());

6.2.4. MTOM threshold

As discussed above, in rare situations where you have a lot of tiny attachments, the overhead of MTOM may outweigh the benefit of binary transfer. To cope with this situation, the JAX-WS RI supports the notion of "threshold" --- if an attachment is smaller than the size specified in threshold, it will simply inline the binary data as base64 binary instead of making it an attachment. Because of the way MTOM spec is designed, such inline vs attachment decision is handled by the toolkits of both ends and will not harm the application running on both sides.

There are two ways to control the threshold:

  1. By using the com.sun.xml.ws.developer.JAXWSProperties.MTOM_THRESHOLD_VALUE property in the RequestContext on the client side and in the MessageContext on the server side.
  2. By adding parameter to the @MTOM annotation, such as @MTOM(threshold=3000)
  3. By adding parameter to the MTOMFeature object, such as new MTOM(3000)

6.2.5. .NET interoperability

6.2.5.1. Using Metro distribution

MTOM support is fully interoperable with .NET clients and servers. If you are working with Metro then your MTOM solution as a endpoint or as client will work out of the box.

6.2.5.2. Using JAX-WS RI distribution

If you are using JAX-WS RI distribution, MTOM interop with .NET client or server will not work out of the box. The reason behind this is that JAX-WS RI does not have built in support for WS-Policy and .NET 3.0/.NET 3.5 looks for an MTOM policy assertion in the WSDL before turning on MTOM encoding. So, you will need to turn it on explicitly on your .NET 3.0/3.5 or JAX-WS RI client.

The MTOM policy assertion that .NET 3.0/.NET 3.5 understands is: <wsoma:OptimizedMimeSerialization/>

6.2.5.2.1. JAX-WS RI endpoint and .NET client

Turn on MTOM explicitly on your .NET client using the WCF editor available with Visual Studio 2005.

6.2.5.2.2. JAX-WS RI client and .NET endpoint

Turn on MTOM on JAX-WS RI client as defined above.

Here is a sample Metro MTOM endpoint and a .NET 3.0 client.


Terms of Use; Privacy Policy; Copyright ©2013-2014 (revision 20131025.e7cbc9d)
 
 
Close
loading
Please Confirm
Close