Sending and Receiving attachments using the SOAP MessageTransmission Optimization Mechanism (MTOM) in JAX-WS 2.0
This techtip will focus on how to send and receive attachments using
the SOAP MessageTransmission Optimization Mechanism (MTOM) feature in JAX-WS 2.0.
The example code below was developed and tested using a GlassFish implementation.
A downloadable zip file that contains everything necessary to build and run this
example is provided at the end of this techtip.
To understand the attachments based on MTOM in JAX-WS 2.0 you will
need to be familiar with the following specifications:
http://www.w3.org/TR/soap12-mtom/
This MTOM example will demonstrate the sending of multiple types of attachments
and verify their contents. Along with sending/receiving the attachments,
there is a server side handler that is configured which will display the
contents of the HTTP request and response to the GlassFish webserver log. It is done
so that you can see the Content-type header contains the entry "type="application/xop+xml"
which indicates that MTOM is being used.
This example makes use of customization files to configure package names and the server
side handler. There is also a directory named contentRoot which contains the various
documents that will be used by this example.
Although this is a very simplistic example it does show the use of MTOM and the
sending and receiving of various kinds of documents. Certainly a user
could expand and enhance this example to do far greater things.
Developing the WebService Server Side Endpoint
Step 1
Create your wsdl description for your webservices endpoint which will send and
receive messages.
a) MTOMTestService.wsdl
The following wsdl was used to develop this example. Notice that there are three
operations MTOMIn, MTOMInOut, and MTOMTestOut and one port MTOMPort that have been specified for the three tests that will be run.
Create and implement a common class that will be used to deal with
the various attachments.
a) AttachmentHelper.java
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package mtomtest.common;
import java.awt.*;
import java.util.*;
import java.io.*;
import java.net.URL;
import java.awt.image.*;
import javax.xml.soap.AttachmentPart;
import javax.xml.transform.stream.StreamSource;
import javax.activation.DataHandler;
import javax.xml.transform.Source;
public class AttachmentHelper {
public static Iterator getAttachments(Iterator iter) {
while(iter.hasNext()) {
Object obj = iter.next();
if(!(obj instanceof AttachmentPart)) {
return null;
}
}
return iter;
}
public static AttachmentPart getAttachment(java.net.URI ref, Iterator iter) {
if(iter == null || ref == null) {
System.out.println("null Iterator for AttachmentPart");
return null;
}
while(iter.hasNext()) {
AttachmentPart tempAttachment = (AttachmentPart)iter.next();
if(ref.isOpaque() && ref.getScheme().equals("cid")) {
String refId = ref.getSchemeSpecificPart();
String cId = tempAttachment.getContentId();
if(cId.equals("<"+refId+">") || cId.equals(refId)) {
return tempAttachment;
}
}
}
return null;
}
public static boolean compareStreamSource(StreamSource src1, StreamSource src2, int length) throws Exception {
if(src1 == null || src2 == null) {
System.out.println("compareStreamSource - src1 or src2 null!");
return false;
}
String in = getStringFromStreamSource(src1, length);
String out = getStringFromStreamSource(src2, length);
if(in == null)
System.out.println("src1 is null");
if(out == null)
System.out.println("src2 is null");
return in.equals(out);
}
private static String getStringFromStreamSource(StreamSource src, int length) throws Exception {
byte buf[]=null;
if(src == null)
return null;
InputStream outStr = src.getInputStream();
if(outStr != null) {
int len = outStr.available(); if(outStr.markSupported())outStr.reset();
buf = new byte[len];
outStr.read(buf, 0, len);
System.out.println("From inputstream: "+new String(buf));
return new String(buf);
}else {
char buf1[] = new char[length];
Reader r = src.getReader();
if(r == null)
return null;
r.reset();
r.read(buf1);
System.out.println("From Reader: "+new String(buf));
return new String(buf1);
}
}
public static boolean compareImages(Image image1, Image image2) throws IOException {
if (image1 == null || image2 == null)
return false;
boolean matched = false;
Rectangle rect = new Rectangle(0, 0, convertToBufferedImage(image1).getWidth(), convertToBufferedImage(image1).getHeight());
Iterator iter1 = handlePixels(image1, rect);
Iterator iter2 = handlePixels(image2, rect);
while (iter1.hasNext() && iter2.hasNext()) {
Pixel pixel = (Pixel) iter1.next();
if (pixel.equals((Pixel) iter2.next())) {
matched = true;
} else {
matched = false;
}
}
if (matched)
return true;
return false;
}
public static boolean compareImages(Image image1, Image image2, Rectangle rect) {
if(image1 == null || image2 == null)
return false;
boolean matched = false;
Iterator iter1 = handlePixels(image1, rect);
Iterator iter2 = handlePixels(image2, rect);
while(iter1.hasNext() && iter2.hasNext()) {
Pixel pixel = (Pixel)iter1.next();
if(pixel.equals((Pixel)iter2.next())) {
matched = true;
}else {
matched = false;
}
}
if(matched)
return true;
return false;
}
public static Iterator handlePixels(Image img, Rectangle rect) {
int x = rect.x;
int y = rect.y;
int w = rect.width;
int h = rect.height;
int[] pixels = new int[w * h];
PixelGrabber pg = new PixelGrabber(img, x, y, w, h, pixels, 0, w);
try {
pg.grabPixels();
} catch (InterruptedException e) {
System.err.println("interrupted waiting for pixels!");
return null;
}
if ((pg.getStatus() & ImageObserver.ABORT) != 0) {
System.err.println("image fetch aborted or errored");
return null;
}
ArrayList tmpList = new ArrayList();
for (int j = 0; j < h; j++) {
for (int i = 0; i < w; i++) {
tmpList.add(handleSinglePixel(x+i, y+j, pixels[j * w + i]));
}
}
return tmpList.iterator();
}
private static Pixel handleSinglePixel(int x, int y, int pixel) {
int alpha = (pixel >> 24) & 0xff;
int red = (pixel >> 16) & 0xff;
int green = (pixel >> 8) & 0xff;
int blue = (pixel ) & 0xff;
return new Pixel(alpha, red, green, blue);
}
private static class Pixel {
private int a;
private int r;
private int g;
private int b;
Pixel(int a, int r, int g, int b) {
this.a = a;
this.r = r;
this.g = g;
this.b = b;
}
protected boolean equals(Pixel p) {
if(p.a == a && p.r == r && p.g == g && p.b == b)
return true;
return false;
}
}
private static BufferedImage convertToBufferedImage(Image image) throws IOException {
if (image instanceof BufferedImage) {
return (BufferedImage)image;
} else {
MediaTracker tracker = new MediaTracker(null/*not sure how this is used*/);
tracker.addImage(image, 0);
try {
tracker.waitForAll();
} catch (InterruptedException e) {
throw new IOException(e.getMessage());
}
BufferedImage bufImage = new BufferedImage(
image.getWidth(null),
image.getHeight(null),
BufferedImage.TYPE_INT_RGB);
Graphics g = bufImage.createGraphics();
g.drawImage(image, 0, 0, null);
return bufImage;
}
}
public static Image getImageDoc(URL url) throws Exception {
System.out.println("url="+url);
return javax.imageio.ImageIO.read(url);
}
public static String getStringDoc(URL url) throws Exception {
System.out.println("url="+url);
DataHandler dh = new DataHandler(url);
byte[] bytes = new byte[8192];
int count = dh.getInputStream().read(bytes, 0, 8192);
String string = new String(bytes, 0, count);
return string;
}
public static StreamSource getSourceDoc(URL url) throws Exception {
System.out.println("url="+url);
DataHandler dh = new DataHandler(url);
StreamSource source = new StreamSource(dh.getInputStream());
return source;
}
public static DataHandler getDataHandlerDoc(URL url) throws Exception {
System.out.println("url="+url);
DataHandler dh = new DataHandler(url);
return dh;
}
public static String ValidateAttachmentData(String expectedDoc, String actualDoc, String whichAttachment)
{
String result = null;
if (actualDoc != null){
if (!actualDoc.equals(expectedDoc)){
result = "FAILURE: "+whichAttachment+" String documents did not compare correctly";
System.out.println("========================");
System.out.println(whichAttachment+" comparison failed");
System.out.println("expected:");
System.out.println("------------------------");
System.out.println(expectedDoc);
System.out.println("------------------------");
System.out.println("actual:");
System.out.println("------------------------");
System.out.println(actualDoc);
System.out.println("------------------------");
}
} else {
result = "FAILURE: "+whichAttachment+" actual String document was null";
}
if(result != null) result += "\n";
return result;
}
public static String ValidateAttachmentData(DataHandler expectedDoc, DataHandler actualDoc, String whichAttachment) throws Exception {
byte data[] = new byte[4096];
int count = expectedDoc.getInputStream().read(data, 0, 4096);
String strExpected = new String(data, 0, count);
count = actualDoc.getInputStream().read(data, 0, 4096);
String strActual = new String(data, 0, count);
String result = ValidateAttachmentData(strExpected, strActual, whichAttachment);
return result;
}
public static String ValidateAttachmentData(Source expectedDoc, Source actualDoc, String whichAttachment) throws Exception {
String result = null;
boolean debug = false;
if (actualDoc!= null){
byte data1[] = new byte[8192];
byte data2[] = new byte[8192];
int count1 = 0;
int count2 = 0;
int tmpcount = 0;
InputStream is = ((StreamSource)expectedDoc).getInputStream();
while(tmpcount != -1) {
tmpcount = is.read(data1, count1, 8192-count1);
if(tmpcount != -1) count1 += tmpcount;
if(tmpcount == 0) break;
}
if(count1 == 0) count1 = -1;
tmpcount = 0;
is = ((StreamSource)actualDoc).getInputStream();
while(tmpcount != -1) {
tmpcount = is.read(data2, count2, 8192-count2);
if(tmpcount != -1) count2 += tmpcount;
if(tmpcount == 0) break;
}
if(count2 == 0) count2 = -1;
if(debug) {
System.out.println("Sending doc1 to file /tmp/"+whichAttachment);
FileOutputStream fos = new FileOutputStream("/tmp/"+whichAttachment);
fos.write(data1, 0, count1);
fos.close();
System.out.println("Sending doc2 to file /tmp/"+whichAttachment+".mtom");
fos = new FileOutputStream("/tmp/"+whichAttachment+".mtom");
fos.write(data2, 0, count2);
fos.close();
}
} else {
result = "FAILURE: "+whichAttachment+" actual XML document was null";
}
if(result != null) result += "\n";
return result;
}
public static String ValidateAttachmentData(Image image1, Image image2, String whichAttachment) throws IOException {
String result = null;
if (image2 != null){
if (!compareImages(image1, image2, new Rectangle(0,0,100,120))) {
System.out.println(whichAttachment+" comparison failed");
result="FAILURE: "+whichAttachment+" Image documents did not compare correctly";
}
} else {
result = "FAILURE: "+whichAttachment+" actual Image document was null";
}
if(result != null) result += "\n";
return result;
}
public static void dumpByteArrays(byte[] b1, int c1, byte[] b2, int c2, String whichAttachment)
{
System.out.println("in dumpByteArrays");
boolean error_found=false;
StringBuffer s1 = new StringBuffer();
StringBuffer s2 = new StringBuffer();
int nexti = 0;
for(int i=0; i c1 || i > c2) {
nexti = i;
break;
}
s1.append((char)b1[i]);
s2.append((char)b2[i]);
if(b1[i] != b2[i]) {
if (!error_found){
System.out.println("FAILURE begins at (index="+i+")");
System.out.printf("byte1[%d]=0x%x|0%o|%d, byte2[%d]=0x%x|0%o|%d, count1=%d, count2=%d\n",
i, b1[i], b1[i], b1[i], i, b2[i], b2[i], b2[i], c1, c2);
error_found=true;
}
nexti = i+1;
break;
}
}
int i = nexti;
int count =0;
while(i < c1 && count < 10) {
s1.append((char)b1[i++]);
count++;
}
i = nexti;
count = 0;
while(i < c2 && count < 10) {
s2.append((char)b2[i++]);
count++;
}
System.out.println("--------------------------------------------");
System.out.println("doc1 upto point of error (Expected "+whichAttachment+" document)\n"+s1.toString());
System.out.println("--------------------------------------------");
System.out.println("doc2 upto point of error (Actual "+whichAttachment+" document)\n"+s2.toString());
System.out.println("========================================================================");
}
public static void dumpSourceDoc(Source s) throws Exception
{
System.out.println("in dumpSourceDoc");
byte data[] = new byte[8192];
int c1 = 0;
int tmpcount = 0;
InputStream is = ((StreamSource)s).getInputStream();
while(tmpcount != -1) {
tmpcount = is.read(data, c1, 8192-c1);
if(tmpcount != -1) c1 += tmpcount;
if(tmpcount == 0) break;
}
System.out.println("========================================================================");
String tmpStr = new String(data, 0, c1);
System.out.println(""+tmpStr);
System.out.println("========================================================================");
}
}
Step 4
Create and implement the code for the webservices server side endpoint along
with the server side handler.
Notice the annotation: @BindingType(SOAPBinding.SOAP11HTTP_MTOM_BINDING) which
is one of the ways to enable MTOM on the server side.
a) MTOMTestImpl.java
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package mtomtest.server;
import javax.jws.WebService;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.Holder;
import java.awt.Image;
import mtomtest.common.AttachmentHelper;
import java.net.URL;
import javax.activation.DataHandler;
import javax.xml.transform.Source;
import javax.xml.ws.BindingType;
import javax.xml.ws.soap.SOAPBinding;
@WebService(
portName="MTOMPort",
targetNamespace="http://MTOMTestService.org/wsdl",
serviceName="MTOMTestService",
wsdlLocation="WEB-INF/wsdl/MTOMTestService.wsdl",
endpointInterface="mtomtest.server.MTOMPortType")
@BindingType(SOAPBinding.SOAP11HTTP_MTOM_BINDING)
public class MTOMTestImpl implements MTOMPortType {
public String mtomIn(mtomtest.server.DataType data) {
System.out.println("--------------------------");
System.out.println("In mtomIn");
String result = "";
try {
String docName1 = data.getDocName1();
String docName2 = data.getDocName2();
String docName3 = data.getDocName3();
String docName4 = data.getDocName4();
System.out.println("docName1="+docName1);
System.out.println("docName2="+docName2);
System.out.println("docName3="+docName3);
System.out.println("docName4="+docName4);
URL docURL1 = new URL(data.getDocUrl1());
URL docURL2 = new URL(data.getDocUrl2());
URL docURL3 = new URL(data.getDocUrl3());
URL docURL4 = new URL(data.getDocUrl4());
System.out.println("docURL1="+docURL1.toString());
System.out.println("docURL2="+docURL2.toString());
System.out.println("docURL3="+docURL3.toString());
System.out.println("docURL4="+docURL4.toString());
Source doc1 = AttachmentHelper.getSourceDoc(docURL1);
Source doc2 = AttachmentHelper.getSourceDoc(docURL2);
DataHandler doc3 = AttachmentHelper.getDataHandlerDoc(docURL3);
Image doc4 = AttachmentHelper.getImageDoc(docURL4);
String tmpRes = AttachmentHelper.ValidateAttachmentData(doc1,data.getDoc1(),docName1);
if (tmpRes != null){
result = result + tmpRes;
}
tmpRes = AttachmentHelper.ValidateAttachmentData(doc2,data.getDoc2(),docName2);
if (tmpRes != null){
result = result + tmpRes;
}
tmpRes = AttachmentHelper.ValidateAttachmentData(doc3,data.getDoc3(),docName3);
if (tmpRes != null){
result = result + tmpRes;
}
tmpRes = AttachmentHelper.ValidateAttachmentData(doc4, data.getDoc4(),docName4);
if (tmpRes != null){
result = result + tmpRes;
}
} catch (Exception e) {
throw new WebServiceException(e.toString());
}
return result;
}
public void mtomInOut(
Holder<String> hDocName1,
Holder<String> hDocName2,
Holder<String> hDocName3,
Holder<String> hDocName4,
Holder<String> hDocUrl1,
Holder<String> hDocUrl2,
Holder<String> hDocUrl3,
Holder<String> hDocUrl4,
Holder<String> hDocUrl11,
Holder<String> hDocUrl12,
Holder<String> hDocUrl13,
Holder<String> hDocUrl14,
Holder<Source> hDoc1,
Holder<Source> hDoc2,
Holder<DataHandler> hDoc3,
Holder<Image> hDoc4,
Holder<String> hResult) {
System.out.println("--------------------------");
System.out.println("In mtomInOut");
String result= "";
try {
String docName1 = hDocName1.value;
String docName2 = hDocName2.value;
String docName3 = hDocName3.value;
String docName4 = hDocName4.value;
System.out.println("docName1="+docName1);
System.out.println("docName2="+docName2);
System.out.println("docName3="+docName3);
System.out.println("docName4="+docName4);
URL docURL1 = new URL(hDocUrl1.value);
URL docURL2 = new URL(hDocUrl2.value);
URL docURL3 = new URL(hDocUrl3.value);
URL docURL4 = new URL(hDocUrl4.value);
System.out.println("docURL1="+docURL1.toString());
System.out.println("docURL2="+docURL2.toString());
System.out.println("docURL3="+docURL3.toString());
System.out.println("docURL4="+docURL4.toString());
Source doc1 = AttachmentHelper.getSourceDoc(docURL1);
Source doc2 = AttachmentHelper.getSourceDoc(docURL2);
DataHandler doc3 = AttachmentHelper.getDataHandlerDoc(docURL3);
Image doc4 = AttachmentHelper.getImageDoc(docURL4);
String tmpRes = AttachmentHelper.ValidateAttachmentData(doc1,hDoc1.value, docName1);
if (tmpRes != null){
result = result + tmpRes;
}
tmpRes = AttachmentHelper.ValidateAttachmentData(doc2,hDoc2.value,docName2);
if (tmpRes != null){
result = result + tmpRes;
}
tmpRes = AttachmentHelper.ValidateAttachmentData(doc3,hDoc3.value,docName3);
if (tmpRes != null){
result = result + tmpRes;
}
tmpRes = AttachmentHelper.ValidateAttachmentData(doc4,hDoc4.value,docName4);
if (tmpRes != null){
result = result + tmpRes;
}
URL docURL11 = new URL(hDocUrl11.value);
URL docURL12 = new URL(hDocUrl12.value);
URL docURL13 = new URL(hDocUrl13.value);
URL docURL14 = new URL(hDocUrl14.value);
System.out.println("docURL11="+docURL11.toString());
System.out.println("docURL12="+docURL12.toString());
System.out.println("docURL13="+docURL13.toString());
System.out.println("docURL14="+docURL14.toString());
hDoc1.value = AttachmentHelper.getSourceDoc(docURL11);
hDoc2.value = AttachmentHelper.getSourceDoc(docURL12);
hDoc3.value = AttachmentHelper.getDataHandlerDoc(docURL13);
hDoc4.value = AttachmentHelper.getImageDoc(docURL14);
hResult.value = result;
} catch (Exception e) {
throw new WebServiceException(e.toString());
}
}
public mtomtest.server.DataType mtomOut(String urls) {
System.out.println("--------------------------");
System.out.println("In mtomOut");
System.out.println("urls="+urls);
String[] tmpUrls = urls.split(",");
for (int i=0;i<tmpUrls.length;i++){
System.out.println("url["+i+"]="+tmpUrls[i]);
}
DataType d = new DataType();
try {
URL docURL1 = new URL(tmpUrls[0]);
URL docURL2 = new URL(tmpUrls[1]);
URL docURL3 = new URL(tmpUrls[2]);
URL docURL4 = new URL(tmpUrls[3]);
d.setDocUrl1(docURL1.toString());
d.setDocUrl2(docURL2.toString());
d.setDocUrl3(docURL3.toString());
d.setDocUrl4(docURL4.toString());
Source doc1 = AttachmentHelper.getSourceDoc(docURL1);
Source doc2 = AttachmentHelper.getSourceDoc(docURL2);
DataHandler doc3 = AttachmentHelper.getDataHandlerDoc(docURL3);
Image doc4 = AttachmentHelper.getImageDoc(docURL4);
d.setDoc1(doc1);
d.setDoc2(doc2);
d.setDoc3(doc3);
d.setDoc4(doc4);
} catch (Exception e) {
throw new WebServiceException(e.toString());
}
return d;
}
}
b) ServerLogicalHandler.java
This is the handler that will display the HTTP header to the webserver log.
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package mtomtest.server;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.LogicalHandler;
import javax.xml.ws.handler.LogicalMessageContext;
import javax.xml.ws.LogicalMessage;
public class ServerLogicalHandler implements LogicalHandler
{
public boolean handleMessage(LogicalMessageContext context)
{
boolean direction= ((Boolean)context.get(LogicalMessageContext.MESSAGE_OUTBOUND_PROPERTY)).booleanValue();
if (direction) {
System.out.println("direction = outbound");
} else {
System.out.println("direction = inbound");
}
displayHeaders(context);
return true;
}
public void close(MessageContext context)
{
}
public boolean handleFault(LogicalMessageContext context)
{
return true;
}
public void displayHeaders(MessageContext context) {
System.out.println("HTTP Headers =|"+ context.get(MessageContext.HTTP_REQUEST_HEADERS)+"|");
return;
}
}
Step 4
Build and compile the webservices server side endpoint code and package it in a war file.
Ensure you are in the directory: mtomtest/src/mtomtest
Execute the command:ant compile-server create-war
The output follows:
compile-server:
[echo] compile-server
[javac] Compiling 3 source files to /home/user/mtomtest/classes
[javac] Note: /home/user/mtomtest/src/mtomtest/common/AttachmentHelper.java uses unchecked or unsafe operations.
[javac] Note: Recompile with -Xlint:unchecked for details.
compile-server-w2j:
[echo] compile-server-w2j
create-war:
[echo] create-war
[echo] Creating war file /home/user/mtomtest/dist/mtomtest/MTOMTestService.war
[mkdir] Created dir: /home/user/mtomtest/dist/mtomtest
[war] Building war: /home/user/mtomtest/dist/mtomtest/MTOMTestService.war
[echo] Created war file /home/user/mtomtest/dist/mtomtest/MTOMTestService.
build-server-w2j:
build-server:
Step 5
Deploy the webservices endpoint packaged in the war to a GlassFish appserver environment.
Ensure you are in the directory: mtomtest/src/mtomtest
Execute the command:ant deploy
The output follows:
Buildfile: build.xml
checkPlatform:
configUnix:
configWindows:
filter.password.file:
[copy] Copying 1 file to /home/user/mtomtest/build
configPlatform:
deploy:
[echo] deploy
[echo] Deploying /home/user/mtomtest/dist/mtomtest/MTOMTestService.war.
[echo] asadmin deploy --user admin --passwordfile /home/user/mtomtest/build/password.txt --host localhost --port 4848 --contextroot MTOMTestService --target server --updload=true
[exec] Command deploy executed successfully.
Step 6
Verify web service application is deployed:
In your browser go to URL location of the published WSDL for this server:
o http://host:port/MTOMTestService/jaxws/MTOMTest?WSDL
where host and port are the settings of your configured GlassFish web server host and port settings,
MTOMTestService is the context root of your web service application, /jaxws/MTOMTest
is the URL alias specified in the web.xml deployment descriptor for deployed endpoint
and ?WSDL is how the published WSDL is accessed.
A WSDL should be displayed if the service is up and running.
Developing WebServices Client Side Code
Step 1
Run wsimport to generate the client side artifacts to communicate with the
webservices endpoint developed in previous section pointing to the wsdl of the
deployed endpoint on a GlassFish appserver environment.
a) Create the customization file for the client side generation.
customfile-client.xml
<!--
Copyright 2006 Sun Microsystems, Inc. All rights reserved.
SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
-->
<jaxws:bindings wsdlLocation="wsdl/MTOMTestService.wsdl" version="2.0"
xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb">
<jaxws:bindings node="wsdl:definitions">
<jaxws:package name="mtomtest.client"/>
</jaxws:bindings>
<jaxws:bindings node="wsdl:definitions/wsdl:types/xs:schema[@targetNamespace='http://MTOMTestService.org/types']" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<jxb:schemaBindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb">
<jxb:package name="mtomtest.client"/>
</jxb:schemaBindings>
</jaxws:bindings>
</jaxws:bindings>
b) Run wsimport to generate the client side artifacts to communicate with
the endpoint developed in the previous section pointing to the wsdl of the
deployed endpoint on a GlassFish appserver environment using the above
customization file.
This is one way to enable MTOM on the client side.
a) Client.java
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package mtomtest.client;
import mtomtest.common.AttachmentHelper;
import java.io.*;
import java.net.*;
import java.util.*;
import java.awt.Image;
import javax.xml.soap.*;
import javax.activation.DataHandler;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.ws.Holder;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.soap.SOAPBinding;
import javax.xml.ws.WebServiceRef;
import javax.xml.namespace.QName;
public class Client {
private static MTOMPortType port = null;
@WebServiceRef
private static MTOMTestService service = null;
final String NAMESPACEURI = "http://MTOMTestService.org/wsdl";
final String PORT_NAME = "MTOMTestPort";
final QName PORT_QNAME = new QName(NAMESPACEURI, PORT_NAME);
final String PROTOCOL="http";
private static String host="localhost";
private static int portnum=8001;
final String ctxroot = "/MTOMTestService";
final String SDOC1="text.xml";
final String SDOC2="application.xml";
final String SDOC3="attach.html";
final String SDOC4="attach.jpg";
final String SDOC11="text2.xml";
final String SDOC12="application2.xml";
final String SDOC13="attach2.html";
final String SDOC14="attach2.jpg";
private URL docURL1 = null;
private URL docURL2 = null;
private URL docURL3 = null;
private URL docURL4 = null;
private URL docURL11 = null;
private URL docURL12 = null;
private URL docURL13 = null;
private URL docURL14 = null;
public static void main(String[] args ) {
Client client = new Client();
try {
int i=0;
while (i < args.length) {
System.out.println("args["+i+"]="+args[i]);
if (args[i].equals("-host")){
host=args[++i];
i++;
continue;
}
if (args[i].equals("-portnum")){
portnum=Integer.parseInt(args[++i]);
i++;
continue;
}
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("------------------------------------------");
System.out.println("Executing Tests");
System.out.println("------------------------------------------");
client.doTests();
}
public void doTests() {
doMTOMInTest();
doMTOMInOutTest();
doMTOMOutTest();
}
public boolean setup() {
boolean result=true;
System.out.println("Protocol="+PROTOCOL);
System.out.println("Host="+host);
System.out.println("portnum="+portnum);
try {
docURL1 = new URL(PROTOCOL, host, portnum, ctxroot + "/" + SDOC1);
docURL2 = new URL(PROTOCOL, host, portnum, ctxroot + "/" + SDOC2);
docURL3 = new URL(PROTOCOL, host, portnum, ctxroot + "/" + SDOC3);
docURL4 = new URL(PROTOCOL, host, portnum, ctxroot + "/" + SDOC4);
docURL11 = new URL(PROTOCOL, host, portnum, ctxroot + "/" + SDOC11);
docURL12 = new URL(PROTOCOL, host, portnum, ctxroot + "/" + SDOC12);
docURL13 = new URL(PROTOCOL, host, portnum, ctxroot + "/" + SDOC13);
docURL14 = new URL(PROTOCOL, host, portnum, ctxroot + "/" + SDOC14);
} catch (Exception e) {
e.printStackTrace();
result=false;
}
port = service.getMTOMPort();
System.out.println("port="+port);
SOAPBinding binding = (SOAPBinding)((BindingProvider)port).getBinding();
binding.setMTOMEnabled(true);
return result;
}
public void doMTOMInTest() {
System.out.println("doMTOMInTest");
boolean pass = true;
if (setup()){
try {
DataType data = new DataType();
data.setDocName1(SDOC1);
data.setDocName2(SDOC2);
data.setDocName3(SDOC3);
data.setDocName4(SDOC4);
data.setDocUrl1(docURL1.toString());
data.setDocUrl2(docURL2.toString());
data.setDocUrl3(docURL3.toString());
data.setDocUrl4(docURL4.toString());
StreamSource doc1 = AttachmentHelper.getSourceDoc(docURL1);
StreamSource doc2 = AttachmentHelper.getSourceDoc(docURL2);
DataHandler doc3 = AttachmentHelper.getDataHandlerDoc(docURL3);
Image doc4 = AttachmentHelper.getImageDoc(docURL4);
data.setDoc1(doc1);
data.setDoc2(doc2);
data.setDoc3(doc3);
data.setDoc4(doc4);
System.out.println("Send 4 documents using MTOM via webservice method mtomIn()");
System.out.println("Documents to send: ["+SDOC1+","+SDOC2+","+SDOC3+","+SDOC4+"]");
String result = port.mtomIn(data);
if (!result.equals("")){
System.err.println("An error occurred with one or more of the attachments");
System.err.println("result="+result);
pass=false;
}
} catch (Exception e) {
e.printStackTrace();
pass=false;
}
} else {
pass=false;
}
if (pass)
System.out.println("doMTOMInTest PASSED");
else
System.err.println("doMTOMInTest FAILED");
}
public void doMTOMInOutTest() {
System.out.println("doMTOMInOutTest");
boolean pass = true;
if (setup()) {
try {
Holder hDocName1 = new Holder(SDOC1);
Holder hDocName2 = new Holder(SDOC2);
Holder hDocName3 = new Holder(SDOC3);
Holder hDocName4 = new Holder(SDOC4);
Holder hDocUrl1 = new Holder(docURL1.toString());
Holder hDocUrl2 = new Holder(docURL2.toString());
Holder hDocUrl3 = new Holder(docURL3.toString());
Holder hDocUrl4 = new Holder(docURL4.toString());
Holder hDocUrl11 = new Holder(docURL11.toString());
Holder hDocUrl12 = new Holder(docURL12.toString());
Holder hDocUrl13 = new Holder(docURL13.toString());
Holder hDocUrl14 = new Holder(docURL14.toString());
StreamSource doc1 = AttachmentHelper.getSourceDoc(docURL1);
StreamSource doc2 = AttachmentHelper.getSourceDoc(docURL2);
DataHandler doc3 = AttachmentHelper.getDataHandlerDoc(docURL3);
Image doc4 = AttachmentHelper.getImageDoc(docURL4);
Holder hDoc1 = new Holder(doc1);
Holder hDoc2 = new Holder(doc2);
Holder hDoc3 = new Holder(doc3);
Holder hDoc4 = new Holder(doc4);
Holder hResult = new Holder(new String());
System.out.println("Send and receieve 4 documents using MTOM via webservice method mtomInOut()");
System.out.println("Documents to send: ["+SDOC1+","+SDOC2+","+SDOC3+","+SDOC4+"]");
System.out.println("Documents to receive: ["+SDOC11+","+SDOC12+","+SDOC13+","+SDOC14+"]");
port.mtomInOut(hDocName1,hDocName2,hDocName3,hDocName4,
hDocUrl1,hDocUrl2,hDocUrl3,hDocUrl4,
hDocUrl11,hDocUrl12,hDocUrl13,hDocUrl14,
hDoc1,hDoc2,hDoc3,hDoc4,hResult);
if (!(hResult.value).equals("")){
System.err.println("Server-side errors occurred:\n"+ hResult.value);
pass=false;
}
System.out.println("Verify the contents of the received documents");
doc1 = AttachmentHelper.getSourceDoc(docURL11);
doc2 = AttachmentHelper.getSourceDoc(docURL12);
doc3 = AttachmentHelper.getDataHandlerDoc(docURL13);
doc4 = AttachmentHelper.getImageDoc(docURL14);
// Now test the documents that were sent back by Server
String tmpRes = AttachmentHelper.ValidateAttachmentData(doc1,hDoc1.value, SDOC11);
if (tmpRes != null){
System.err.println("Client-side error: "+tmpRes);
pass = false;
}
tmpRes = AttachmentHelper.ValidateAttachmentData(doc2,hDoc2.value,SDOC12);
if (tmpRes != null){
System.err.println("Client-side error: "+tmpRes);
pass = false;
}
tmpRes = AttachmentHelper.ValidateAttachmentData(doc3,hDoc3.value,SDOC13);
if (tmpRes != null){
System.err.println("Client-side error: "+tmpRes);
pass = false;
}
tmpRes = AttachmentHelper.ValidateAttachmentData(doc4,hDoc4.value,SDOC14);
if (tmpRes != null){
System.err.println("Client-side error: "+tmpRes);
pass = false;
}
if(pass) {
System.out.println("All received documents are as expected (ok)");
}
} catch (Exception e) {
e.printStackTrace();
pass=false;
}
} else {
pass=false;
}
if (pass)
System.out.println("doMTOMInOutTest PASSED");
else
System.err.println("doMTOMInOutTest FAILED");
}
public void doMTOMOutTest() {
System.out.println("doMTOMOutTest");
boolean pass = true;
if (setup()) {
try {
StreamSource doc1 = AttachmentHelper.getSourceDoc(docURL1);
StreamSource doc2 = AttachmentHelper.getSourceDoc(docURL2);
DataHandler doc3 = AttachmentHelper.getDataHandlerDoc(docURL3);
Image doc4 = AttachmentHelper.getImageDoc(docURL4);
String urls = docURL1.toString()+","+docURL2.toString()+
","+docURL3.toString()+","+docURL4.toString();
System.out.println("urls="+urls);
System.out.println("Receive 4 documents using MTOM via webservice method mtomOut()");
System.out.println("Documents to receive: ["+SDOC1+","+SDOC2+","+SDOC3+","+SDOC4+"]");
DataType data = port.mtomOut(urls);
System.out.println("Verify the contents of the received documents");
String tmpRes = AttachmentHelper.ValidateAttachmentData(doc1,data.getDoc1(), SDOC1);
if (tmpRes != null){
System.err.println("Client-side error: "+tmpRes);
pass = false;
}
tmpRes = AttachmentHelper.ValidateAttachmentData(doc2,data.getDoc2(),SDOC2);
if (tmpRes != null){
System.err.println("Client-side error: "+tmpRes);
pass = false;
}
tmpRes = AttachmentHelper.ValidateAttachmentData(doc3,data.getDoc3(),SDOC3);
if (tmpRes != null){
System.err.println("Client-side error: "+tmpRes);
pass = false;
}
tmpRes = AttachmentHelper.ValidateAttachmentData(doc4,data.getDoc4(),SDOC4);
if (tmpRes != null){
System.err.println("Client-side error: "+tmpRes);
pass = false;
}
if(pass) {
System.out.println("All received documents are as expected (ok)");
}
} catch (Exception e) {
e.printStackTrace();
pass=false;
}
} else {
pass=false;
}
if (pass)
System.out.println("doMTOMOutTest PASSED");
else
System.err.println("doMTOMOutTest FAILED");
}
}
Step 3
Build and compile the client code.
Ensure you are in the directory: mtomtest/src/mtomtest
Execute the command:ant compile-client
The output follows:
Buildfile: build.xml
compile-client:
[echo] compile-client
[javac] Compiling 9 source files to /home/user/mtomtest/classes
Step 4
Run the client code which will communicate with the deployed webservices endpoint
Ensure you are in the directory: mtomtest/src/mtomtest
Execute the command:ant runclient
The output follows:
Buildfile: build.xml
checkPlatform:
configUnix:
configWindows:
filter.password.file:
[copy] Copying 1 file to /home/user/mtomtest/build
configPlatform:
runclient:
[echo] runclient mtomtest.client.Client
[exec] args[0]=-host
[exec] args[2]=-portnum
[exec] ------------------------------------------
[exec] Executing Tests
[exec] ------------------------------------------
[exec] doMTOMInTest
[exec] Protocol=http
[exec] Host=localhost
[exec] portnum=8001
[exec] port=com.sun.xml.ws.client.EndpointIFInvocationHandler@171194d
[exec] url=http://localhost:8001/MTOMTestService/text.xml
[exec] url=http://localhost:8001/MTOMTestService/application.xml
[exec] url=http://localhost:8001/MTOMTestService/attach.html
[exec] url=http://localhost:8001/MTOMTestService/attach.jpg
[exec] Send 4 documents using MTOM via webservice method mtomIn()
[exec] Documents to send: [text.xml,application.xml,attach.html,attach.jpg]
[exec] MTOMEnabled=true
[exec] doMTOMInTest PASSED
[exec] doMTOMInOutTest
[exec] Protocol=http
[exec] Host=localhost
[exec] portnum=8001
[exec] port=com.sun.xml.ws.client.EndpointIFInvocationHandler@11e1bbf
[exec] url=http://localhost:8001/MTOMTestService/text.xml
[exec] url=http://localhost:8001/MTOMTestService/application.xml
[exec] url=http://localhost:8001/MTOMTestService/attach.html
[exec] url=http://localhost:8001/MTOMTestService/attach.jpg
[exec] Send and receieve 4 documents using MTOM via webservice method mtomInOut()
[exec] Documents to send: [text.xml,application.xml,attach.html,attach.jpg]
[exec] Documents to receive: [text2.xml,application2.xml,attach2.html,attach2.jpg]
[exec] Verify the contents of the received documents
[exec] url=http://localhost:8001/MTOMTestService/text2.xml
[exec] url=http://localhost:8001/MTOMTestService/application2.xml
[exec] url=http://localhost:8001/MTOMTestService/attach2.html
[exec] url=http://localhost:8001/MTOMTestService/attach2.jpg
[exec] All received documents are as expected (ok)
[exec] doMTOMInOutTest PASSED
[exec] doMTOMOutTest
[exec] Protocol=http
[exec] Host=localhost
[exec] portnum=8001
[exec] port=com.sun.xml.ws.client.EndpointIFInvocationHandler@c7057c
[exec] url=http://localhost:8001/MTOMTestService/text.xml
[exec] url=http://localhost:8001/MTOMTestService/application.xml
[exec] url=http://localhost:8001/MTOMTestService/attach.html
[exec] url=http://localhost:8001/MTOMTestService/attach.jpg
[exec] urls=http://localhost:8001/MTOMTestService/text.xml,http://localhost:8001/MTOMTestService/application.xml,http://localhost:8001/MTOMTestService/attach.html,http://localhost:8001/MTOMTestService/attach.jpg
[exec] Receive 4 documents using MTOM via webservice method mtomOut()
[exec] Documents to receive: [text.xml,application.xml,attach.html,attach.jpg]
[exec] Verify the contents of the received documents
[exec] All received documents are as expected (ok)
[exec] doMTOMOutTest PASSED
BUILD SUCCESSFUL
Total time: 24 seconds
Sample code
A sample package which provides the complete example of the techniques covered
by this techtip is downloadable from
here
The sample package includes the source code, required descriptor files, and
the build scripts inorder to build the example.
Steps to install and run the sample:
Step 1. Download GlassFish from the GlassFish Project page.
Step 2. Set the following environment variables:
ANT_HOME - path to location of Ant installation. This example uses Ant 1.6.5.
JAVA_HOME - path to location of JDK5.0 installation.
Also, add the Ant location to your PATH environment variable.
Step 3. Download the sample package and extract its contents.
To get started using this techtip all you have to edit is the
following file:
o mtomtest/build/common.properties
The main properties to set are the ones listed below based on your
glassfish installation properties. You should check the others to ensure
they are also correct
<!-- Main Properties to Set -->
<!-- Only these need be set -->
<property name="jdk.home" value="/jdk1.5.0"/>
<property name="appserver.home" value="/sun/appserver9"/>
<property name="tests.home" value="/home/user/mtomtest"/>
<property name="webserver.host" value="localhost"/>
<property name="webserver.port" value="8001"/>
Step 4. Start the GlassFish Application Server
Step 5. cd mtomtest/src/mtomtest
Step 6. Type the following to build, deploy and run the sample:
ant
Hey, Thanks for doing this! I was able to get everything to work after editing common.properties and adding a line to Client.java. Inside the setup method, I put
service = new MTOMTestService(); just before
port = service.getMTOMPort();
Posted by
Pam Holzner
on May 22, 2008 at 01:18 PM EDT
#
Hey, Thanks for doing this! I was able to get everything to work after editing common.properties and adding a line to Client.java. Inside the setup method, I put
service = new MTOMTestService(); just before
port = service.getMTOMPort();
Posted by Pam Holzner on May 22, 2008 at 01:18 PM EDT #