Chapter 11.  Use MTOM and MIME in a SOAP web service.

11.1.  Use MTOM on the service.

11.1.1.  Use @MTOM annotation with a web service.

javax.xml.ws.soap.MTOM


@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@WebServiceFeatureAnnotation(id=MTOMFeature.ID,bean=MTOMFeature.class)
public @interface MTOM {
    /**
     * Specifies if this feature is enabled or disabled.
     */
    boolean enabled() default true;

    /**
     * Property for MTOM threshold value. When MTOM is enabled, binary data above this
     * size in bytes will be XOP encoded or sent as attachment. The value of this property
     * MUST always be >= 0. Default value is 0.
     */
    int threshold() default 0;
}

						

With Java API for XML-Based Web Services (JAX-WS), you can send binary attachments such as images or files along with web services requests. JAX-WS adds support for optimized transmission of binary data as specified by the SOAP Message Transmission Optimization Mechanism (MTOM) specification.

JAX-WS supports the use of SOAP Message Transmission Optimized Mechanism (MTOM) for sending binary attachment data. By enabling MTOM, you can send and receive binary data optimally without incurring the cost of data encoding needed to embed the binary data in an XML document.

JAX-WS applications can send binary data as base64 or hexBinary encoded data contained within the XML document. However, to take advantage of the optimizations provided by MTOM, enable MTOM to send binary base64 data as attachments contained outside the XML document. MTOM optimization is not enabled by default. JAX-WS applications require separate configuration of both the client and the server artifacts to enable MTOM support. For the server, you can enable MTOM on a JavaBean endpoint only and not on endpoints that implement the javax.xml.ws.Provider interface.

Procedure:

  1. Develop Java artifacts for your JAX-WS application that includes an XML schema or Web Services Description Language (WSDL) file that represents your web services application data that includes a binary attachment.

    1. If you are starting with a WSDL file, develop Java artifacts from a WSDL file by using the wsimport command to generate the required JAX-WS portable artifacts.

    2. If you are starting with JavaBeans components, develop Java artifacts for JAX-WS applications and optionally generate a WSDL file using the wsgen command. The XML schema or WSDL file includes a xsd:base64Binary or xsd:hexBinary element definition for the binary data.

    3. You can also include the xmime:expectedContentTypes attribute on the element to affect the mapping by JAXB.

  2. Enable MTOM on a JavaBean endpoint.

    To enable MTOM on an endpoint, use the @MTOM (javax.xml.ws.soap.MTOM) annotation on the endpoint. The @MTOM annotation has two parameters: enabled and threshold. The enabled parameter has a boolean value and indicates if MTOM is enabled for the JAX-WS endpoint. The threshold parameter has an integer value, and it specifies the minimum size for messages that are sent using MTOM. When the message size is less than this specified integer, the message is inlined in the XML document as base64 or hexBinary data.

    To enable MTOM in the web service, specify the @java.xml.ws.soap.MTOM annotation on the service endpoint implementation class, as illustrated in the following example. Relevant code is shown in bold:

    package examples.webservices.mtom;
    
    import javax.jws.WebMethod;
    import javax.jws.WebService;
    import javax.xml.ws.soap.MTOM;
    
    @MTOM
    @WebService(name="MtomPortType",
                serviceName="MtomService",
                targetNamespace="http://example.org")
    public class MTOMImpl {
      @WebMethod
      public String echoBinaryAsString(byte[] bytes) {
        return new String(bytes);
      }
    }
    									

    Additionally, you can use the @BindingType (javax.xml.ws.BindingType) annotation on a server endpoint implementation class to specify that the endpoint supports one of the MTOM binding types so that the response messages are MTOM-enabled. The javax.xml.ws.SOAPBinding class defines two different constants, SOAP11HTTP_MTOM_BINDING and SOAP12HTTP_MTOM_BINDING that you can use for the value of the @BindingType annotation.

    // for SOAP version 1.1
    @BindingType(value = SOAPBinding.SOAP11HTTP_MTOM_BINDING)
    
    // for SOAP version 1.2
    @BindingType(value = SOAPBinding.SOAP12HTTP_MTOM_BINDING)
    									

11.1.2.  Use MTOM policy in WSDL.

Following WSDL example demonstrates use of the Optimized Mime Serialization policy assertion:

  1 <wsdl:definitions
  2         targetNamespace="example.com"
  3         xmlns:tns="example.com"
  4         xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
  5         xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
  6         xmlns:wsoma="http://schemas.xmlsoap.org/ws/2004/09/policy/optimizedmimeserialization"
  7         xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" >
  8     <wsp:Policy wsu:Id="MyPolicy" >
  9         <wsoma:OptimizedMimeSerialization />
 10         <!-- omitted assertions -->
 11     </wsp:Policy>
 12     <!-- omitted elements -->
 13     <wsdl:binding name="MyBinding" type="tns:MyPortType" >
 14         <wsp:PolicyReference
 15             URI="#MyPolicy"
 16             wsdl:required="true" />
 17         <!-- omitted elements -->
 18     </wsdl:binding>
 19 </wsdl:definitions>

Lines (8-11) in are a policy expression that includes an Optimized Mime Serialization policy assertion (Line 9) to indicate that the SOAP Message Transmission Optimization Mechanism (MTOM) may be used.

Lines (13-18) are a WSDL binding. Lines (14-16) indicate that the policy in Lines (8-11) applies to this binding, specifically indicating that MTOM encodings must be accepted over all the messages in the binding. Line (16) indicates policy is a required extension.

MTOM is used to optimize the transmission of SOAP message over the wire. MTOM uses a wire format of a SOAP message by selectively encoding portions of the message, whilst still presenting an XML Infoset to the SOAP application. Optimization is available only for element content that is in a canonical lexical representation of the xs:base64Binary data type.

Message Part: Consider a message with one of it part as base64Binary:


<message name="mtomOperationRequest">
    <part name="part1" type="xsd:string"/>
    <part name="part2" type="xsd:base64Binary"/>
</message>

						

Binding: it shows how the binding use the MTOM policy:


<binding name="mtomBinding" type="tns:mtomPortType">
    <wsp:PolicyReference URI="#mtomBindingPolicy"/>
    <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="mtomOperation">
        <soap:operation/>
        <input name="input1">
            <soap:body use="literal" namespace="http://j2ee.netbeans.org/wsdl/mtomBP/mtom"/>
        </input>
        ...
</binding>

						

MTOM policy:


<wsp:Policy wsu:Id="mtomBindingPolicy">
    <wsp:ExactlyOne>
        <wsp:All>
            <wsoma:OptimizedMimeSerialization/>
        </wsp:All>
    </wsp:ExactlyOne>
</wsp:Policy>

						

The wire format below show how the SOAP envelope is transmitted using HTTP, take a note of the part2 which represent the binary data and how the data is trasmitted, note the data is not part of the SOAP envelope, instead it is transmitted as a separate MIME part:


POST /mtomService/mtomPort HTTP/1.1
SOAPAction: ""
Accept: text/xml, multipart/related, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Content-Type: multipart/related;
       start="<rootpart*b0ef6adc-44fa-47ba-a7a7-95915eb54d9e@example.jaxws.sun.com>";
       type="application/xop+xml";
       boundary="uuid:b0ef6adc-44fa-47ba-a7a7-95915eb54d9e";
       start-info="text/xml"
User-Agent: JAX-WS RI 2.1.4.1-hudson-346-
Host: localhost:9088
Connection: keep-alive
Content-Length: 890

--uuid:b0ef6adc-44fa-47ba-a7a7-95915eb54d9e
Content-Id: <rootpart*b0ef6adc-44fa-47ba-a7a7-95915eb54d9e@example.jaxws.sun.com>
Content-Type: application/xop+xml;charset=utf-8;type="text/xml"
Content-Transfer-Encoding: binary

<?xml version='1.0' encoding='UTF-8'?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Body>
        <ns2:mtomOperation xmlns:ns2="http://j2ee.netbeans.org/wsdl/mtomBP/mtom">
            <part1>hello</part1>
            <part2>
                <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include"
                    href="cid:2f3a859b-6cdb-4eba-8163-0365521f094c@example.jaxws.sun.com" />
            </part2>
        </ns2:mtomOperation>
    </S:Body>
</S:Envelope>
--uuid:b0ef6adc-44fa-47ba-a7a7-95915eb54d9e
Content-Id: <2f3a859b-6cdb-4eba-8163-0365521f094c@example.jaxws.sun.com>
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary

[BINARY ATTACHMENT]

--uuid:b0ef6adc-44fa-47ba-a7a7-95915eb54d9e--

						

Some of the points to note in the above wire format example are:

  • The binary attachment is packaged in a MIME multi-part message.

  • An <xop:Include> element is used to mark where the binary data is.

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

If binary data is sent as inlined, then the runtime has to encode the data to xs:base64Binary, which bloats the data by 33%, 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. One can control the behavior of the runtime by using the MTOM threshold provided by the JAX-WS RI, 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.

11.1.3.  Use MTOM in the deployment descriptors

You can enable MTOM on server by using the enable-mtom attribute in the sun-jaxws.xml configuration file. This allows the MTOM setting to be changed at deployment time:


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

						

11.1.4.  Use MTOMFeature with javax.xml.ws.Endpoint API

javax.xml.ws.soap.MTOMFeature

The MTOMFeature is used to specify if MTOM should be used with a web service. This feature should be used instead of the javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_MTOM_BINDING, javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_MTOM_BINDING and the javax.xml.ws.soap.SOAPBinding.setMTOMEnabled(). This feature MUST be supported with the SOAP 1.1/HTTP or SOAP 1.2/HTTP bindings. Using this feature with any other bindings is undefined. This feature corresponds to the @MTOM annotation.

Enabling this feature on either the server or client will result the JAX-WS runtime using MTOM and for binary data being sent as an attachment.

The MTOMFeature has one property threshold, that can be configured to serve as a hint for which binary data SHOULD be sent as an attachment. The threshold is the size in bytes that binary data SHOULD be in order to be sent as an attachment. The threshold MUST not be negative. The default value is 0.

11.1.5.  Use swaRef in WSDL.

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.

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.

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_5_32550604.1118953563502"
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"?>
[ATTACHMENT CONTENT]
------=_Part_5_32550604.1118953563502

						

11.1.6.  Use MIME binding in WSDL

blah-blah

Professional hosting         'Oracle Certified Expert Web Services Developer 6' Quiz     Free SCDJWS 5.0 Guide