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.
About this task
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.
The
application server supports sending attachments using MTOM only for
JAX-WS applications. This product also provides the ability to provide
attachments with Web Services Security SOAP messages by using the
new MTOM and XOP standards.
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.
Procedure
- 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.
- 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.
- 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.
- You can also include the xmime:expectedContentTypes attribute
on the element to affect the mapping by JAXB.
- Enable MTOM on your endpoint implementation class using
one of the following methods:
- Use the @MTOM annotation on the 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, that must be greater than or equal to zero.
When MTOM is enabled, any binary data whose size, in bytes, exceeds
the threshold value is XML-binary Optimized Packaging (XOP) encoded
or sent as an attachment. When the message size is less than the threshold
value, the message is inlined in the XML document as either base64
or hexBinary data.
The following example snippet illustrates
adding the @MTOM annotation so that MTOM is enabled for the JAX-WS
MyServiceImpl endpoint
and specifies a threshold value of 2048 bytes:
@MTOM(enabled=true, threshold=2048)
@WebService
public class MyServiceImpl {
...
}
Additionally, you can use the @BindingType (javax.xml.ws.BindingType)
annotation on an 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 example:
// This example is for SOAP version 1.1.
@BindingType(value = SOAPBinding.SOAP11HTTP_MTOM_BINDING)
@WebService
public class MyServiceImpl {
...
}
// This example is for SOAP version 1.2.
@BindingType(value = SOAPBinding.SOAP12HTTP_MTOM_BINDING)
@WebService
public class MyServiceImpl {
...
}
The presence and value of an @MTOM annotation
overrides the value of the @BindingType annotation. For example,
if the @BindingType indicates MTOM is enabled, but an @MTOM annotation
is present with an enabled value of false,
then MTOM is not enabled.
- Use the <enable-mtom> and <mtom-threshold> deployment
descriptor elements.
You can use the
<enable-mtom> and
<mtom-threshold> elements
within the
<port-component> element in the
webservices.xml deployment descriptor as an alternative to using the
@MTOM annotation on the service endpoint implementation class; for
example:
<port-component>
<port-component-name>MyPort1</port-component-name>
<enable-mtom>true</enable-mtom>
<mtom-threshold>2048</mtom-threshold>
<service-impl-bean>
<servlet-link>MyPort1ImplBean</servlet-link>
</service-impl-bean>
</port-component>
Avoid trouble: The
deployment descriptor elements take precedence over the corresponding
attributes in the MTOM annotation. For example, if the
enabled attribute
is set to
true in the annotation, but the
<enable-mtom> element
is set to
false in the
webservices.xml file,
MTOM is not enabled for the corresponding endpoint.
gotcha
- Enable MTOM on your client to optimize the binary messages
that are sent from the client to the server. Use one of
the following methods to enable MTOM on your client:
- Enable MTOM on a Dispatch client.
The following examples
use SOAP version 1.1.
The first method uses SOAPBinding.setMTOMEnabled();
for example:
SOAPBinding binding = (SOAPBinding)dispatch.getBinding();
binding.setMTOMEnabled(true);
The second method
uses Service.addPort; for example:
Service svc = Service.create(serviceName);
svc.addPort(portName,SOAPBinding.SOAP11HTTP_MTOM_BINDING,endpointUrl);
The
third method uses MTOMFeature; for example:
MTOMFeature mtom = new MTOMFeature(true, 2048);
Service svc = Service.create(serviceName);
svc.addPort(portName, SOAPBinding.SOAP11_HTTP_BINDING, endpointUrl);
Dispatch<Source> dsp = svc.createDispatch(portName, Source.class, Service.Mode.PAYLOAD, mtom);
- Enable MTOM on a Dynamic Proxy client.
// Create a BindingProvider bp from a proxy port.
Service svc = Service.create(serviceName);
MtomSample proxy = svc.getPort(portName, MtomSample.class);
BindingProvider bp = (BindingProvider) proxy;
//Enable MTOM using the SOAPBinding.
MtomSample proxy = svc.getPort(portName, MtomSample.class);
BindingProvider bp = (BindingProvider) proxy;
SOAPBinding binding = (SOAPBinding) bp.getBinding();
binding.setMTOMEnabled(true);
//Or, you can enable MTOM with the MTOMFeature.
MTOMFeature mtom = new MTOMFeature();
MtomSample proxy = svc.getPort(portName, MtomSample.class, mtom);
- Enable MTOM on your client using the @MTOM annotation; for
example:
public class MyClientApplication {
// Enable MTOM for a port-comonent-ref resource injection.
@MTOM(enabled=true, threshold=1024)
@WebServiceRef(MyService.class)
private MyPortType myPort;
...
}
- Enable MTOM on your client using deployment descriptor elements
within a port-component-ref element; for example:
<service-ref>
<service-ref-name>service/MyPortComponentRef</service-ref-name>
<service-interface>com.example.MyService</service-ref-interface>
<port-component-ref>
<service-endpoint-interface>com.example.MyPortType</service-endpoint-interface>
<enable-mtom>true</enable-mtom>
<mtom-threshold>1024</mtom-threshold>
</port-component-ref>
</service-ref>
Avoid trouble: The deployment
descriptor elements take precedence over the corresponding attributes
in the MTOM annotation. For example, if the
enabled attribute
is set to
true in the annotation, but the
<enable-mtom> element
is set to
false in the deployment descriptor entry
for the service-ref of the client, MTOM is not enabled for that service
reference.
gotcha
Results
You have developed a JAX-WS web services server and client
application that optimally sends and receives binary data using MTOM.
Example
The following example illustrates enabling MTOM support
on both the web services client and server endpoint when starting
with an WSDL file.
- Locate the WSDL file containing an xsd:base64Binary element.
The following example is a portion of a WSDL file that contains an xsd:base64Binary element.
<types>
........
<xs:complexType name="ImageDepot">
<xs:sequence>
<xs:element name="imageData"
type="xs:base64Binary"
xmime:expectedContentTypes="image/jpeg"/>
</xs:sequence>
</xs:complexType>
........
</types>
- Run the wsimport command from the app_server_root\bin\
directory against the WSDL file to generate a set of JAX-WS portable
artifacts.
Depending
on the
expectedContentTypes value contained in the
WSDL file, the JAXB artifacts generated are in the Java type
as described in the following table:
Table 1. Mapping of MIME type and Java type. Describes
the mapping between MIME types and Java types. MIME Type |
Java Type |
image/gif |
java.awt.Image |
image/jpeg |
java.awt.Image |
text/plain |
java.lang.String |
text/xml |
javax.xml.transform.Source |
application/xml |
javax.xml.transform.Source |
*/* |
javax.activation.DataHandler |
- Use the JAXB artifacts in the same manner as in any other JAX-WS
application. Use these beans to send binary data from both the Dispatch
and the Dynamic Proxy client APIs.
- Enable MTOM on a Dispatch client.
//Create the Dispatch instance.
JAXBContext jbc = JAXBContext.newInstance("org.apache.axis2.jaxws.sample.mtom");
Dispatch<Object> dispatch = svc.createDispatch(portName, jbc, Service.Mode.PAYLOAD);
//Enable MTOM.
SOAPBinding binding = (SOAPBinding) dispatch.getBinding();
binding.setMTOMEnabled(true);
- Enable MTOM on a Dynamic Proxy client.
//Create the Dynamic Proxy instance.
Service svc = Service.create(serviceName);
MtomSample proxy = svc.getPort(portName, MtomSample.class);
//Enable MTOM.
BindingProvider bp = (BindingProvider) proxy;
SOAPBinding binding = (SOAPBinding) bp.getBinding();
binding.setMTOMEnabled(true);
Now that you have
enabled the JAX-WS client for MTOM, messages sent to the server have
MTOM enabled. However, for the server to respond back to the client
using MTOM, you must enable MTOM on the endpoint.
- Enable MTOM on the endpoint implementation class.
@MTOM(enabled, threshold=4096)
@WebService (endpointInterface="org.apache.axis2.jaxws.sample.mtom.MtomSample")
public class MtomSampleService implements MtomSample {
....
}
The jaxax.xml.ws.SOAPBinding class has
a static member for each of the supported binding types. Include either
the SOAP11HTTP_MTOM_BINDING or the SOAP12HTTP_MTOM_BINDING as
the value for the @BindingType annotation. This value
enables all server responses to have MTOM enabled.
When you enable MTOM on the server and the client, the binary
data that represents the attachment is included as a Multipurpose
Internet Mail Extensions (MIME) attachment to the SOAP message. Without
MTOM, the same data is encoded in the format that describes the XML
schema, either base64 or hexadecimal encoding, and included inline
in the XML document.
This example illustrates an MTOM enabled
SOAP version 1.1 message with an attachment. The
type and
content-type attributes
both have the value,
application/xop+xml, which indicates
that the message was successfully optimized using XML-binary Optimized
packaging (XOP) when MTOM was enabled. This example demonstrates how
the optimized message looks on the wire with MTOM enabled.
... other transport headers ...
Content-Type: multipart/related; boundary=MIMEBoundaryurn_uuid_0FE43E4D025F0BF3DC11582467646812;
type="application/xop+xml"; start="
<0.urn:uuid:0FE43E4D025F0BF3DC11582467646813@apache.org>"; start-info="text/xml"; charset=UTF-8
--MIMEBoundaryurn_uuid_0FE43E4D025F0BF3DC11582467646812
content-type: application/xop+xml; charset=UTF-8; type="text/xml";
content-transfer-encoding: binary
content-id:
<0.urn:uuid:0FE43E4D025F0BF3DC11582467646813@apache.org>
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<sendImage xmlns="http://org/apache/axis2/jaxws/sample/mtom">
<input>
<imageData>
<xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include"
href="cid:1.urn:uuid:0FE43E4D025F0BF3DC11582467646811@apache.org"/>
</imageData>
</input>
</sendImage>
</soapenv:Body>
</soapenv:Envelope>
--MIMEBoundaryurn_uuid_0FE43E4D025F0BF3DC11582467646812
content-type: text/plain
content-transfer-encoding: binary
content-id:
<1.urn:uuid:0FE43E4D025F0BF3DC11582467646811@apache.org>
… binary data goes here …
--MIMEBoundaryurn_uuid_0FE43E4D025F0BF3DC11582467646812--
In contrast, this example demonstrates a SOAP version
1.1 message on the wire without MTOM enabled. The binary data is included
in the body of the SOAP message, and the SOAP message is not optimized.
... other transport headers ...
Content-Type: text/xml; charset=UTF-8
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<sendImage xmlns="http://org/apache/axis2/jaxws/sample/mtom">
<input>
<imageData>R0lGADl ... more base64 encoded data ... KTJk8giAAA7</imageData>
</input>
</sendImage>
</soapenv:Body>
</soapenv:Envelope>
For additional information, refer to the Samples
section of the Information Center which includes a sample that demonstrates
the use of MTOM with JAX-WS web services.