# Java TM API for XML Web Services
(JAX-WS)
MTOM and Swaref

Specification Version: 2.2
Implementation Version: 2.2.5

- Overview
- Provider
- AsyncProvider
- Dispatch
- Asynchronous Client
- Handler
- MTOM and Swaref
- SOAP 1.2
- WSDL Customization
- Annotations
- WS-Addressing
- Stateful Webservice
- Catalog
- Interoperability

## Contents

1. MTOM and XOP
2. MTOM in JAX-WS 2.0
2.1 xmime:expectedContentTypes to Java type mapping
2.2 xmime:contentType schema annotation
2.3 How to enable MTOM in JAX-WS 2.0
2.4 Attach vs In-line
2.5 MTOM Samples
3. swaRef
3.1 swaRef in JAX-WS 2.0
3.2 How to use swaRef
3.3 swaRef Sample

## 1. MTOM and XOP

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.

## 2. MTOM in JAX-WS 2.0

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. Currently MTOM works only with proxy port.

### 2.1 xmime:expectedContentType to Java type mapping

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 in Table 9-1. Here is this table:

MIME Type | Java Type
image/gif | java.awt.Image
image/jpeg | java.awt.Image
text/plain | java.lang.String
text/xml or application/xml | javax.xml.transform.Source
*/* | 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

### 2.2 xmime:contentType schema annotation

xmime:contentType schema annotation indicates the content-type of an XML element content whose type is xs:base64Binary or xs:hexBinary. The value of the attribute is a valid content-type string (e.g., "text/xml; charset=utf-16"). This attribute specifies the content-type of the element content on which it occurs. This annotation can be primarily used to indicate the Content-Type of binary data.

For example the schema type

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

Gets mapped to PicutreType bean by wsimport:

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

On the wire this is how it looks:

`<?xml version="1.0" ?>
<soapenv:Envelope xmlns:soapenv=" 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">
<soapenv:Body>
<ns1:TestMtomXmimeContentTypeResponse ns2:contentType="application/xml">
<xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="c id:193ed174-d313-4325-8eed-16cc25595e4e@example.org"/>
</ns1:TestMtomXmimeContentTypeResponse>
</soapenv:Body>
</soapenv:Envelope>`

### 2.3 How to enable MTOM in JAX-WS 2.0

Enabling MTOM on Server:

- Enable using @javax.xml.ws.soap.MTOM annotation on the endpoint (SEI) implementation class

              @javax.xml.ws.soap.MTOM
              @WebService (endpointInterface = "mtom.server.Hello")
              public class HelloImpl implements Hello {
                  ....
                  ....
              }

- MTOM can be also be enabled on an endpoint by specifying enable-mtom attribute to true on an endpoint element in sun-jaxws.xml deployment descriptor.

                  <?xml version="1.0" encoding="UTF-8"?>
                  <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>

- Enable using @BindingType on the endpoint (SEI) implementation class
  - `@BindingType(value=javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_MTOM_BINDING)` will enable MTOM on the deployed endpoint for SOAP 1.1 binding
  - `@BindingType(value=javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_MTOM_BINDING)` will enable MTOM on the deployed endpoint for SOAP 1.2 binding

Enabling MTOM on Client:

- To enable MTOM on client-side, pass javax.xml.ws.soap.MTOMFeature as WebServiceFeature parameter while crating the Proxy or Dispatch. Here is the code snippet from the client MtomApp.java of the mtom sample:

  - Hello port = new HelloService().getHelloPort(new MTOMFeature()); gives a proxy with MTOM enabled
  - javax.xml.ws.Service.createDispatch(....,new javax.xml.ws.soap.MTOMFeature()) gives a Dispatch instance with MTOM enabled
- JAX-WS 2.0 specification has defined API to enable and to check if the MTOM is enabled.
  - javax.xml.ws.soap.SOAPBinding.setMTOMEnabled(boolean enable) - enable or disable MTOM.
  - javax.xml.ws.soap.SOAPBinding.isMTOMEnabled() - returns true if MTOM is enabled otherwise false.

          Hello port = new HelloService.getHelloPort();
          //get the binding and enable mtom
          SOAPBinding binding = (SOAPBinding)((BindingProvider)port).getBinding();
          boolean mtomEnabled = binding.isMTOMEnabled();
          binding.setMTOMEnabled(true);

### 2.4 Attach vs In-line

As defined by JAXB 2.0 specification xs:base64Binary and xs:hexBinary mapping to java is byte[]. JAX-WS 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.

#### 2.4.1 How to specify MTOM data Threshold

Default threshold value for MTOM feature is 0 bytes. You can set a threshold value for MTOM by using @MTOM annotation on server-side or using MTOMFeature on client-side. Let's say you set MTOM threshold as 3000, this serves as hint to JAX-WS when to send binary dat as attachments. In this case, JAX-WS will send any byte array in the message thats equal to or larger than 3KB as attachment and the corresponding XML infoset will be XOP encoded (will contain reference to this attachment)

- On Server-side, @MTOM(threshold=3000)
- On Client-side, pass MTOMFeature(3000) as WebServiceFeature as mentioned in section 2.3, while creating the proxy/dispatch.

### 2.5 MTOM Samples

There are 2 samples:

#### 2.5.1 mtom

This is SOAP 1.1 MTOM SampleThis is how the JAX-WS generated XOP packaged SOAP message looks on the wire:

    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

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

     </xop:Include>
     </image>
     </Detail>
     </soapenv:Body>
    </soapenv:Envelope>

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

     ╪
        α ►JFIF ☺☻ ☺ ☺ █ ♠♠
    ♀¶
    ♀♂♂♀↓↕‼☼¶↔→▼▲↔→∟∟
        $.' ",#∟∟(7),01444▼'9=82<.342 █ C☺ ♀♂♀↑↑2!∟!22222222222222222222222222222222222222222222

    222222 └ ) ¬♥☺" ☻◄☺♥◄☺ ─ ▼ ☺♣☺☺☺☺☺☺
        ☺☻♥♦ ♂ ─ ╡► ☻☺♥♥☻♦♥♣♣♦♦
        ☺}☺☻♥ ♦◄♣↕!1A♠‼Qa"q¶2?#B▒┴§R╤≡$3bré

    ▬↨↑↓→%&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzâäàåçêëèÆôöòûùÿÖÜóúñÑªº¿⌐¬▓│┤╡╢╖╕╣║┬├─┼╞╟╚╔╩╥╙╘╒╓╫╪┘┌ßΓπΣσµτΦΘΩ±≥≤⌠⌡÷≈°∙·
        ─

Above Photo is inlined binary data because its less than 1KB and image which is more than 1KB is sent as attachment.
Here is the associated schema:

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

     <!-- mapped to byte[] -->
     <element name="Photo" type="base64Binary"/>
     <!-- mapped to
        java.awt.Image -->
     <element name="image" type="base64Binary" xmime:expectedContentTypes="image/jpeg"/>
     </sequence>
    </complexType>

#### 2.5.2 mtom-soap12

This is SOAP 1.2 MTOM Sample. Here is how the JAX-WS generated soap message looks on the wire:

    <element name="image" type="base64Binary" xmime:expectedContentTypes="image/jpeg"/>

    Content-Type:
        Multipart/Related; start-info="application/soap+xml"; type="application/xop+xml";
        boundary="----=_Part_0_1744155.1118960238280"
    Content-Length: 1946
    SOAPAction: ""

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

    <soapenv:Envelope
        xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
     <soapenv:Body>
     <Detail
        xmlns="http://example.org/mtom/data">
     <Photo>RHVrZQ==</Photo>
     <image>
                    <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:42a7ee0a-20ee-426b-a135-094d72bc138f@example.org">

     </xop:Include>
     </image>
     </Detail>
     </soapenv:Body>
    </soapenv:Envelope>

    ------=_Part_1_4558657.1118960238320
    Content-Type: application/octet-stream
    Content-ID: <42a7ee0a-20ee-426b-a135-094d72bc138f@example.org>

     ╪ α ►JFIF ☺☻ ☺ ☺ █ ♠♠
    ♀¶

        ♀♂♂♀↓↕‼☼¶↔→▼▲↔→∟∟
        $.' ",#∟∟(7),01444▼'9=82<.342 █ C☺ ♀♂♀↑↑2!∟!22222222222222222222222222222222222222222222

    222222 └ ' )♥☺" ☻◄☺♥◄☺ ─ ▼ ☺♣☺☺☺☺☺☺
        ☺☻♥♦ ♂ ─ ╡► ☻☺♥♥☻♦♥♣♣♦♦
        ☺}☺☻♥ ♦◄♣↕!1A♠‼Qa"q¶2?#B▒┴§R╤≡$3bré

    ▬↨↑↓→%&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzâäàåçêëèÆôöòûùÿÖÜóúñÑªº¿⌐¬▓│┤╡╢╖╕╣║┬├─┼╞╟╚╔╩╥╙╘╒╓╫╪┘┌ßΓπΣσµτΦΘΩ±≥≤⌠⌡÷≈°∙·
        ─
     ▼☺ ♥☺☺☺☺☺☺☺☺☺ ☺☻♥♦

## 3. swaRef

WS-I Attachment Profile 1.0 defines mechanism to reference MIME attachment parts using swaRef. In this mechanism the content of XML element of type wsi:swaRef is sent as MIME attachment and the element inside SOAP Body holds the reference to this attachment in the CID URI scheme as defined by RFC 2111.

### 3.1 swaRef in JAX-WS 2.0

JAXB 2.0 defines mapping of wsi:swaRef schema type to javax.activation.DataHandler. An application will construct the DataHandler with the data and the appropriate MIME type and JAX-WS will coordinate with JAXB and SAAJ to send it as attachment MIME part.

### 3.2 How to use swaRef

An XML element of type wsi:swaRef is mapped to a DataHandler and is sent as attachment over the wire.
For example,

    <element name="claimForm" type="wsi:swaRef" xmlns:wsi="http://ws-i.org/profiles/basic/1.1/xsd"/>

will be sent over the wire as :

    Content-Type: Multipart/Related; start-info="text/xml"; type="application/xop+xml";
        boundary="----=_Part_4_32542424.1118953563492"
    Content-Length: 1193
    SOAPAction: ""

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

        <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
     <soapenv:Body>
     <claimForm
        xmlns="http://example.org/mtom/data">cid:b0a597fd-5ef7-4f0c-9d85-6666239f1d25@example.jaxws.sun.com</claimForm>

     </soapenv:Body>
    </soapenv:Envelope>

    ------=_Part_5_32550604.1118953563502

        Content-Type: application/xml
    Content-ID: <b0a597fd-5ef7-4f0c-9d85-6666239f1d25@example.jaxws.sun.com>

    <?xml
        version="1.0" encoding="UTF-8"?>
    <application xmlns="http://java.sun.com/xml/ns/j2ee"

        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocaption="http://java.sun.com/xml/ns/j2ee

        http://java.sun.com/xml/ns/j2ee/application_1_4.xsd"
     version="1.4">
     <display-name>Simple example of
        application</display-name>
     <description>Simple example</description>
     <module>

        <ejb>ejb1.jar</ejb>
     </module>
     <module>
     <ejb>ejb2.jar</ejb>
     </module>

     <module>
     <web>
     <web-uri>web.war</web-uri>
     <context-root>web</context-root>

     </web>
     </module>
    </application>

### 3.3 swaRef Sample

Refer to swaRef sample testSwaRef () method in MimeApp.java.