Downloading files using SwA (Soap With Attachments)
SOAP based web services over HTTP have the ability to send and receive attachments (aka SwA). In fact there are multiple ways in which attachments can be sent with a web service response. The most simple way is to encode the file data as characters and embed coded characters as body of SOAP message response. Another way is to send a reference to the binary data which is external to SOAP message but is part of the HTTP response. Both these approaches are shown below with the help of example. The corresponding SOAP response clearly shows how does the one differs from other.

Without MTOM
Let us first see how to send attachment from server to client without using MTOM:
ImageService
package com.sample;
import java.awt.Image;
import java.io.IOException;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
@WebService
@SOAPBinding(style=Style.RPC)
public interface ImageService {
public Image getImage(String name) throws IOException;
}
ImageServiceImpl
package com.sample;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.jws.WebService;
import javax.xml.ws.soap.MTOM;
@WebService(endpointInterface="com.sample.ImageService")
public class ImageServiceImpl implements ImageService {
@Override
public Image getImage(String name) throws IOException {
BufferedImage bufImage = ImageIO.read(new File("c://images//" + name));
return bufImage;
}
}
ImageServicePublisher
package com.sample;
import javax.xml.ws.Endpoint;
import com.sample.ImageServiceImpl;
public class ImageServicePublisher {
public static void main(String[] args) {
Endpoint.publish("http://localhost:9999/com.sample",new ImageServiceImpl());
}
}
ImageClient
package com.sample;
import java.io.IOException;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
public class ImageClient {
public static void main(String[] args) throws IOException {
URL url = new URL("http://localhost:8080/com.sample?wsdl");
QName qname = new QName("http://sample.com/","ImageServiceImplService");
Service service = Service.create(url, qname);
ImageService sp = service.getPort(ImageService.class);
System.out.println(sp.getImage("rss.jpg"));
}
}
SOAP response:
HTTP/1.1 200 OK Transfer-encoding: chunked Content-type: text/xml;charset="utf-8" 5e <?xml version="1.0" ?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body> 1000 <ns2:getImageResponse xmlns:ns2="http://sample.com/"><return>iVBORw0KGgoAAAANSUhEUgAAAMkAAACQCAIAAAAtJdhtAACAAElEQVR42uy9B3Rb15W2jck/k0kmTibxTLrtVMdxXBLHdmSrWb13qlAiRYpN7BJ7771TbCIlkmLvKCQaAbD33jsJECR6B9E77ncuQMmynWQyGU+cyW+sd90FXrAB98He7z5nnwOEyQwBmS03yPqFyWiR9T4EZLYIfGUwQxoIUkOQ1gzpwYPgUeNTgftmWODb9JbvsUpvgAz6XRkNsMBPAe3+RbPRIv3H+vL2N7mZ//dviP+SLRiA59jSQjBeOgtOVph2wYJlgr+0nADfoLUcTc9+3GT5rZY7RuPz/wOM18fHL2//MGw9/8VTnna1G1nMu2DtsmWCpbec2WULjl4myKCDjLDMJp0JjlZ6PSyj+TNPyWQyGY3Gj/+O5Wk+DWTmL6/6Pzhbz5/7FHI6g15v1BkMOpNRb4XJIg2kkUNauVmnMBvkJpPCBCmNkNIExzjDs7AGRzGz0WQywGwBYp/7tQZo986Xt38ctp46HmtK2r196sI/kyWuaD92UyYVZFBCBjksjQTSSiC9FDJKIGgHgmQQJLUclZYfsQqYNDiqGc0G658wWNAzWCyawfLll3T9w7L11LibnyUsq54GMZ0FFzEsoxjSCSAVF1JwzXIWJGNBCiakYkM6DmTgQWYeBAEJIKMQMkkg047ZLIcFqSz1AGDL+Awv/VMBvL5k6x+ILZMe1ifZMjyVhQAjHFbgIk4HmRWQmgEp1807yxrhgpwzK96a4lMnuOtjks1pcF/KnJKxp5S8aZ1wVi+a0UsX9EqqXkXXa5lGwBzgzCy1RjJLADNa/taXbP2jswU7oU+AZaVKB9eFZpVFCsgkUrJHVYy+HVoXb4W8NUtcG8ctDrXO9aPWxgnrE3jqNB6cZC0QeEsEwQpRsE7SSWY1Owt6xYpJQ4P0DMgssORKBfwLIY31jz7LjF+y9Y/F1m5xZwAW2wLT7giEzqC2hBK1WS8xawVmDVslWOWt91JH6zZHnix0lawN1c731WzPtW/Nk7irffz1AfpcO3+tZ3GgbnO8aXO0hjZUsT5YLljFcteI/HWycLN7hz2ilSyY1XQ4aRpFkHEHMqrMJq3lT5t3BzQsN4PlBlt+eAzt/4/X+Iti6HNkEbE7avBJtkAEMRiVFsMuM6qYMs6saHOQOU/aGKlf6S6iDxbTh8uXekrme56sjjQx5kms5U6TZEXNmVIwhrmLeOZk82JHwWpXPn+6hjtby5mr58418pfR4o12OaNPy5/UiRf00g2DkgHpRZYUqX7q9PXQ0zLVZLn9w49K/COzZTJqrWyB9PTcgIDWcsllIMAo2BP06dalvspZUuFUW/pye9oKOZXWXzRLfgBiGAhd0921lJbC+uK4TmTBCPExa6ZVvNTGGH6y2VMgmiznjJSwRoEescfLudN1goVmySpOskHZ2R5U86ZNcipk5D+tKK2J0gD9sSGxL9n6v8eW0aAxmXWWAXGTZRZHbzBrjEY5fLGNfCVncmsKNU95OIlJnWyJmWgKXyHGz7ZGA8IWO/KpozWzPVVjHVXd2LLqgpjKvAjvW4c8bN7L8Ds ........................................ ........................................
As we can see that the image data is being sent as part of the SOAP message body. You may download the working application of downloading image contents from server which is sent as character data:
Using MTOM to send binary data
Now let us make a small change to the Service Implementation Bean class as shown below:
ImageServiceImpl
package com.sample;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.jws.WebService;
@WebService(endpointInterface="com.sample.ImageService")
@MTOM
public class ImageServiceImpl implements ImageService {
@Override
public Image getImage(String name) throws IOException {
BufferedImage bufImage = ImageIO.read(new File("c://images//" + name));
return bufImage;
}
}
Thus we simply directed JAX-WS to use MTOM so that the extra work of encoding and decoding binary data to character data on both the sides can be avoided. Now run the web service publisher and client and see the SOAP message by using a message interceptor.
SOAP response:
The SOAP response in this case is reproduced here:
HTTP/1.1 200 OK Transfer-encoding: chunked Content-type: multipart/related;start="<rootpart*d1b00b0a-ad74-44a6-8408-ecd55207d30b@example.jaxws.sun.com>";type="application/xop+xml";boundary="uuid:d1b00b0a-ad74-44a6-8408-ecd55207d30b";start-info="text/xml" 24a --uuid:d1b00b0a-ad74-44a6-8408-ecd55207d30b Content-Id: <rootpart*d1b00b0a-ad74-44a6-8408-ecd55207d30b@example.jaxws.sun.com> Content-Type: application/xop+xml;charset=utf-8;type="text/xml" Content-Transfer-Encoding: binary <?xml version="1.0" ?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><ns2:getImageResponse xmlns:ns2="http://sample.com/"><return><xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:6a4682ab-ca2a-4943-9469-8de5a9d5b1ee@example.jaxws.sun.com"></xop:Include></return></ns2:getImageResponse></S:Body></S:Envelope> 1000 --uuid:d1b00b0a-ad74-44a6-8408-ecd55207d30b Content-Id: <6a4682ab-ca2a-4943-9469-8de5a9d5b1ee@example.jaxws.sun.com> Content-Type: image/png Content-Transfer-Encoding: binary ‰PNG
The following link can be used to download an application which implements MTOM:
Points to remember
The significant points to remember about attachments with SOAP and MTOM are:
- Without MTOM,Base64 encoding is used to encode binary data to character data and hence results in extra processing.
- The content type of Base64 encoding approach is text/xml and content type “multipart/related” is used with MTOM.
- Since MTOM doesn’t specify the file type hence some DataHandler is required for processing of binary data whereas there is no such requirement in case of base64 encoding.






