Programming Advanced Features of WebLogic Web Services Using JAX-WS

     Previous  Next    Open TOC in new window    View as PDF - New Window  Get Adobe Reader - New Window
Content starts here

Optimizing Binary Data Transmission Using MTOM/XOP

The following sections describe how to use MTOM/XOP to send binary data:

 


Sending Binary Data Using MTOM/XOP

SOAP Message Transmission Optimization Mechanism/XML-binary Optimized Packaging (MTOM/XOP) defines a method for optimizing the transmission of XML data of type xs:base64Binary or xs:hexBinary in SOAP messages. When the transport protocol is HTTP, MIME attachments are used to carry that data while at the same time allowing both the sender and the receiver direct access to the XML data in the SOAP message without having to be aware that any MIME artifacts were used to marshal the base64Binary or hexBinary data. The binary data optimization process involves the following steps: 1) encode the binary data, 2) remove the binary data from the SOAP envelope, 3) compress the binary data, 4) attach the binary data to the MIME package, and 5) add references to the MIME package in the SOAP envelope.

MTOM/XOP support is standard in JAX-WS via the use of JWS annotations. The MTOM specification does not require that, when MTOM is enabled, the Web Service runtime use XOP binary optimization when transmitting base64binary or hexBinary data. Rather, the specification allows the runtime to choose to do so. This is because in certain cases the runtime may decide that it is more efficient to send the binary data directly in the SOAP Message; an example of such a case is when transporting small amounts of data in which the overhead of conversion and transport consumes more resources than just inlining the data as is.

The following Java types are mapped to the base64Binary XML data type, by default: javax.activation.DataHandler, java.awt.Image, and javax.xml.transform.Source. The elements of type base64Binary or hexBinary are mapped to byte[], by default.

The following table summarizes the steps required to use MTOM/XOP to send base64Binary or hexBinary attachments.

Table 5-1 Steps to Use MTOM/XOP to Send Binary Data 
#
Step
Description
1
Annotate the data types that you are going to use as an MTOM attachment. (Optional)
Depending on your programming model, you can annotate your Java class or WSDL to define the content types that are used for sending binary data. This step is optional. By default, XML binary types are mapped to Java byte[]. For more information, see Annotating the Data Types.
2
Enable MTOM on the Web Service.
3
Enable MTOM on the client of the Web Service.
4
Set the attachment threshold.
Set the attachment threshold to specify when the xs:binary64 data is sent inline or as an attachment. See Setting the Attachment Threshold.

Annotating the Data Types

Depending on your programming model, you can annotate your Java class or WSDL to define the MIME content types that are used for sending binary data. This step is optional.

The following table defines the mapping of MIME content types to Java types. In some cases, a default MIME type-to-Java type mapping exists. If no default exists, the MIME content types are mapped to DataHandler.

Table 5-2 Mapping of MIME Content Types to Java Types 
MIME Content 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

The following sections describe how to annotate the data types based on whether you are starting from Java or WSDL.

Annotating the Data Types: Start From Java

When starting from Java, to define the content types that are used for sending binary data, annotate the field that holds the binary data using the @XmlMimeType annotation.

The field that contains the binary data must be of type DataHandler.

The following example shows how to annotate a field in the Java class that holds the binary data.

@WebMethod
@Oneway
public void dataUpload(
@XmlMimeType("application/octet-stream") DataHandler data)
{
}

Annotating the Data Types: Start From WSDL

When starting from WSDL, to define the content types that are used for sending binary data, annotate the WSDL element of type xs:base64Binary or xs:hexBinary using one of the following attributes:

The following example maps the image element of type base64binary to image/gif MIME type (which maps to the java.awt.Image Java type).

<element name="image" type="base64Binary"
xmime:expectedContentTypes="image/gif"
xmlns:xmime="http://www.w3.org/2005/05/xmlmime"/>

Enabling MTOM on the Web Service

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);
  }
}

Enabling MTOM on the Client

To enable MTOM on the client of the Web Service, pass the javax.xml.ws.soap.MTOMFeature as a parameter when creating the Web Service proxy or dispatch, as illustrated in the following example. Relevant code is shown in bold.

package examples.webservices.mtom.client;
import javax.xml.ws.soap.MTOMFeature;
public class Main {
public static void main(String[] args) {
String FOO = "FOO";
MtomService service = new MtomService()
MtomPortType port = service.getMtomPortTypePort(new MTOMFeature());
String result = null;
result = port.echoBinaryAsString(FOO.getBytes());
System.out.println( "Got result: " + result );
}
}

Setting the Attachment Threshold

You can set the attachment threshold to specify when the xs:binary64 data is sent inline or as an attachment. By default, the attachment threshold is 0 bytes—all xs:binary64 data is sent as an attachment.

To set the attachment threshold:

In each of the examples above, if a message is greater than or equal to 3 KB, it will be sent as an attachment. Otherwise, the content will be sent inline, as part of the SOAP message body.

 


Streaming SOAP Attachments

Note: The com.sun.xml.ws.developer.StreamingDataHandler API is supported as an extension to the JAX-WS RI, provided by Sun Microsystems. Because this API is not provided as part of the WebLogic software, it is subject to change.

Using MTOM and the javax.activation.DataHandler and com.sun.xml.ws.developer.StreamingDataHandler APIs you can specify that a Web Service use a streaming API when reading inbound SOAP messages that include attachments, rather than the default behavior in which the service reads the entire message into memory. This feature increases the performance of Web Services whose SOAP messages are particulary large.

The following sections describe how to employ streaming SOAP attachments on the client and server sides.

Client Side Example

The following provides an example that employs streaming SOAP attachments on the client side.

package examples.webservices.mtomstreaming.client;

import java.util.Map;
import java.io.InputStream;
import javax.xml.ws.soap.MTOMFeature;
import javax.activation.DataHandler;
import javax.xml.ws.BindingProvider;
import com.sun.xml.ws.developer.JAXWSProperties;
import com.sun.xml.ws.developer.StreamingDataHandler;
public class Main {
public static void main(String[] args) {
MtomStreamingService service = new MtomStreamingService();
MTOMFeature feature = new MTOMFeature();
MtomStreamingPortType port = service.getMtomStreamingPortTypePort(
feature);
Map<String, Object> ctxt=((BindingProvider)port).getRequestContext();
ctxt.put(JAXWSProperties.HTTP_CLIENT_STREAMING_CHUNK_SIZE, 8192);
DataHandler dh = port.fileUpload(...);
StreamingDataHandler sdh = {StreamingDataHandler)dh;
InputStream in = sdh.readOnce();
...
in.close();
sdh.close();
}
}

The preceding example demonstrates the following:

Server Side Example

The following provides an example that employs streaming SOAP attachments on the server side.

package examples.webservices.mtomstreaming;
import java.io.File;
import java.io.InputStream;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlMimeType;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.soap.MTOM;
import javax.activation.DataHandler;
import com.sun.xml.ws.developer.StreamingDataHandler;
...
@MTOM
@WebService(name="MtomStreaming",
serviceName="MtomStreamingService",
targetNamespace="http://example.org",
wsdlLocation="StreamingImplService.wsdl")
public class StreamingImpl {

// Use @XmlMimeType to map to DataHandler on the client side
public void fileUpload(String fileName,
@XmlMimeType("application/octet-stream")
DataHandler data) {
try {
StreamingDataHandler dh = (StreamingDataHandler) data;
File file = new File(fileName);
dh.moveTo(file);
dh.close();
} catch (Exception e) {
throw new WebServiceException(e);
}
}

The preceding example demonstrates the following:

Configuring Streaming SOAP Attachments

You can configure streaming SOAP attachments on the client and server sides to specify the following:

Configuring Streaming SOAP Attachments on the Server

Note: The com.sun.xml.ws.developer.StreamingAttachment API is supported as an extension to the JDK 6.0, provided by Sun Microsystems. Because this API is not provided as part of the JDK 6.0 kit, it is subject to change.

To configure streaming SOAP attachments on the server, add the @StreamingAttachment annotation on the endpoint implementation. The following example specifies that streaming attachments are to be parsed eagerly and sets the memory threshold to 4MB. Attachments under 4MB are stored in memory.

...
import com.sun.xml.ws.developer.StreamingAttachment;
import javax.jws.WebService;
@StreamingAttachment(parseEagerly=true, memoryThreshold=4000000L)
@WebService(name="HelloWorldPortType", serviceName="HelloWorldService")
public class StreamingImpl {
}

Configuring Streaming SOAP Attachments on the Client

Note: The com.sun.xml.ws.developer.StreamingAttachmentFeature API is supported as an extension to the JDK 6.0, provided by Sun Microsystems. Because this API is not provided as part of the JDK 6.0 kit, it is subject to change.

To configure streaming SOAP attachments on the client, create a StreamingAttachmentFeature object and pass this as an argument when creating the PortType stub implementation. The following example sets the directory in which large attachments are stored to /tmp, specifies that streaming attachments are to be parsed eagerly and sets the memory threshold to 4MB. Attachments under 4MB are stored in memory.

...
import com.sun.xml.ws.developer.StreamingAttachmentFeature;
...
MTOMFeature mtom = new MTOMFeature();
StreamingAttachmentFeature stf = new StreamingAttachmentFeature("/tmp", true, 4000000L);
MtomStreamingService service = new MtomStreamingService();
MtomStreamingPortType port = service.getMtomStreamingPortTypePort(
feature, stf);
...

  Back to Top       Previous  Next