JAX-WS 2.0 Beta
MTOM and swaRef


Last Modified: 11/3/2005

Contents

        1. MTOM and XOP
                2. MTOM in JAXWS 2.0
                        2.1 xmime:expectedContentType to Java type mapping
                        2.2 How to enable MTOM in JAXWS 2.0                       
                        2.3 Attach vs In-line
                        2.4 MTOM Samples       
                3. swaRef
                        3.1 swaRef in JAXWS 2.0
                        3.2 How to use swaRef
                        3.3 swaRef Samples

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 JAXWS 2.0

MTOM feature is disabled in jaxws 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:hexBianry 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 How to enable MTOM in JAXWS 2.0

MTOM can 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"
wsdl="WEB-INF/wsdl/hello.wsdl"
service='{http://example.org/mtom}HelloService'
port='{http://example.org/mtom}HelloPort'
url-pattern="/hello"
enable-mtom="true"/>
</endpoints>

JAXWS 2.0 spcification has defined API to enable and to check if the MTOM is enabled.
Here is the code snippet from the client MtomApp.java of the mtom sample:

//obtain the service from ServiceFactory
ServiceFactory serviceFactory = ServiceFactory.newInstance();
HelloService service = (HelloService)serviceFactory.createService(null, HelloService.class);

//get the port
Object port = service.getHelloPort();

//get the binding and enable mtom
SOAPBinding binding = (SOAPBinding)((BindingProvider)port).getBinding();
binding.setMTOMEnabled(true);

2.3 Attach vs In-line

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.

2.3.1 How to specify MTOM data Threshold

On the client side this property should be set in the RequestContext with the threshold value. The threshold value should be in byte and ofcourse MUST be a postive number.

//JAXWS will send any byte array in the message as attachemnt and the corresponding XML infoset will be
//XOP encoded (will contain reference to this attachment)
bindingProvider.getRequestContext().put(JAXWSProperties.MTOM_THRESHOLD_VALUE, 0);

// JAXWS will send any byte array in the message thats equal to or larger than 3KB as attachemnt
// and the corresponding XML infoset will be XOP encoded (will contain reference to this attachment)
bindingProvider.getRequestContext().put(JAXWSProperties.MTOM_THRESHOLD_VALUE, 3000);


On the server side, this property can be set either of the two ways:
@Resource
private WebServiceContext wsContext;

...
wsContext.getMessageContext().put(com.sun.xml.ws.developer.JAXWSProperties.MTOM_THRESHOLD_VALUE, 3000
);
...
<?xml version="1.0" encoding="UTF-8"?>
<endpoints xmlns='http://java.sun.com/xml/ns/jax-ws/ri/runtime' version='2.0'>
    <endpoint
        name="Hello"
        implementation="xop.hello.server.HelloImpl"
        wsdl="WEB-INF/wsdl/hello.wsdl"
         service='{http://example.org/mtom}HelloService'
         port='{http://example.org/mtom}HelloPort'
         url-pattern="/hello" enable-mtom="true" mtom-threshold-value="0"/>
</endpoints>

2.4 MTOM Samples

There are 2 samples:

2.4.1 mtom

This is SOAP 1.1  MTOM SampleThis is how the JAXWS 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.4.2 mtom-soap12

This is SOAP 1.2 MTOM Sample. Here is how the JAXWS 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 JAXWS 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 JAXWS 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:schemaLocation="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 Samples

There are 2 swaRef samples - mtom and mtom-soap1.2, same mtom samples have operation for swaRef, refer testSwaRef () method in MtomApp.java.