Igor Kromin |   Consultant. Coder. Blogger. Tinkerer. Gamer.

This is an example showing how to create an MTOM/XOP enabled web service that can be deployed in WebLogic.

For those who don't know what it is (from Wikipedia):
MTOM is the W3C Message Transmission Optimization Mechanism, a method of efficiently sending binary data to and from Web services.

MTOM is usually used with the XOP (XML-binary Optimized Packaging).


This example uses SOAP 1.2 bindings. Further, I am specifying the return type as an OUT parameter. I find this a more logical way of returning data from a web method because you can stack up multiple return values this way, instead of being limited to one single return value that Java forces. Hence, the return type of this method is void and the JAX-WS stack handles the rest.

The entire example is built using jwsc and Ant. The build scripts are not shown here.
 WsExampleImpl.java
package net.igorkromin;
import javax.activation.DataHandler;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlMimeType;
import javax.xml.ws.BindingType;
import javax.xml.ws.Holder;
import javax.xml.ws.soap.MTOM;
@WebService(
name="WsExamplePortType",
portName="WsExamplePort",
serviceName="WsExampleService",
targetNamespace="http://igorkromin.net"
)
@SOAPBinding(
style=SOAPBinding.Style.DOCUMENT,
use=SOAPBinding.Use.LITERAL,
parameterStyle=SOAPBinding.ParameterStyle.WRAPPED
)
@BindingType(value = javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)
@MTOM (enabled = true, threshold = 0)
public class WsExampleImpl {
public WsExampleImpl() {
super();
}
@WebMethod()
public void getData(
@XmlElement(required=true)
@WebParam(mode = WebParam.Mode.IN, name = "dataId")
String dataId,
@WebParam(mode = WebParam.Mode.OUT, name = "data")
@XmlMimeType("application/octet-stream")
Holder<DataHandler> data
) {
String returnData = "Some data with ID:" + dataId;
DataHandler dh =
new DataHandler(returnData, "text/plain");
data.value = dh;
}
}




The service itself is quite trivial, it accepts an input parameter dataId and returns a string with the input parameter concatenated. The DataHandler takes care for most of the work here, the returnData string is simply fed into the data handler. You can also use an output stream here too if you have a large amount of data to return. The mime type of the data is easily changeable too, but for example purposes it is set to text/plain.

So lets look at the SOAP request for this service, without the headers it is quite simple:
 SOAP request
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:igor="http://igorkromin.net">
<soap:Header/>
<soap:Body>
<igor:getData>
<dataId>42</dataId>
</igor:getData>
</soap:Body>
</soap:Envelope>


Without setting any additional headers to enable MTOM, the response will come back without MTOM/XOP attachments, the data will simply be inline. WebLogic takes care of this automatically, there is nothing further to do in the actual web service to enable this fall-back mechanism.
 SOAP response (inline Base64)
<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope">
<S:Body>
<ns0:getDataResponse xmlns:ns0="http://igorkromin.net">
<data>U29tZSBkYXRhIHdpdGggSUQ6NDI=</data>
</ns0:getDataResponse>
</S:Body>
</S:Envelope>


However, once the correct MTOM headers are set on the request message, the response changes accordingly:
 SOAP response (MTOM/XOP)
<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope">
<S:Body>
<ns0:getDataResponse xmlns:ns0="http://igorkromin.net">
<data>
<xop:Include href="cid:[email protected]" xmlns:xop="http://www.w3.org/2004/08/xop/include"/>
</data>
</ns0:getDataResponse>
</S:Body>
</S:Envelope>


...in addition there is an attachment that is referenced from inside the xop:Include element:
 SOAP response attachment
--uuid:224b48be-9bba-4424-b8da-f8453b8c41ff
Content-Id: <[email protected]>
Content-Type: text/plain
Content-Transfer-Encoding: binary
Some data with ID:42
--uuid:224b48be-9bba-4424-b8da-f8453b8c41ff--


So that's all there is to it. Enjoy.

-i

A quick disclaimer...

Although I put in a great effort into researching all the topics I cover, mistakes can happen. Use of any information from my blog posts should be at own risk and I do not hold any liability towards any information misuse or damages caused by following any of my posts.

All content and opinions expressed on this Blog are my own and do not represent the opinions of my employer (Oracle). Use of any information contained in this blog post/article is subject to this disclaimer.
Hi! You can search my blog here ⤵
NOTE: (2022) This Blog is no longer maintained and I will not be answering any emails or comments.

I am now focusing on Atari Gamer.