Nikos Maravitsas

About Nikos Maravitsas

Nikos has graduated from the Department of Informatics and Telecommunications of The National and Kapodistrian University of Athens. Currently, his main interests are system’s security, parallel systems, artificial intelligence, operating systems, system programming, telecommunications, web applications, human – machine interaction and mobile development.

JAX-WS Attachment With MTOM

In this tutorial we are going to see how to use JAX-WS along with Message Transmission Optimization Mechanism (MTOM) in order to transfer images from a Web Service endpoint to a Client and vise versa. So, in this example we are going to create a Web Service that a client can use in order to download or upload an image. As we know, Web Services uses SOAP messages to communicate with clients that want to use the service. SOAP is an XML based protocol, so it uses XML-Binary Optimized Packaging (XOP) in order to transmit binary data (like an image) over XMl.

It would be very useful to read JAX-WS Hello World Example – RPC Style before proceeding to this example.
 

1. JAX-WS Web Service End Point

In order to create a Web Service Endpoint:

  • First you have to create a Web Service Endpoint Interface. This interface will contain the declerations of all the methods you want to include in the Web Service.
  • Then you have to create a class that actually implements the above interface, which will be your Endpoint implementation.
  • Finally you create your Endpoint publisher which actually deploys the web service and creates and publishes the endpoint for the specified implementor object at a given address. The necessary server infrastructure will be created and configured by the JAX-WS implementation. You have to run the publisher to make your Web Service available to clients.

Web Service Endpoint Interface (SEI)

ImageServerInterface.java:

package com.javacodegeeks.enterprise.ws.jaxws;

import java.awt.Image;

import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;

@WebService
@SOAPBinding(style = Style.RPC)
public interface ImageServerInterface {

	@WebMethod
	Image downloadImage(String imageName);

	@WebMethod
	String uploadImage(Image imageToUpload);

}

Web Service Endpoint Implementation

ImageServerImpl.java:

package com.javacodegeeks.enterprise.ws.jaxws;

import java.awt.Graphics2D;
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.WebServiceException;
import javax.xml.ws.soap.MTOM;

@MTOM
@WebService(endpointInterface = "com.javacodegeeks.enterprise.ws.jaxws.ImageServerInterface")
public class ImageServerImpl implements ImageServerInterface{

	@Override
	public Image downloadImage(String imageName) {

		try {

			File imageFile = new File("F:\\nikos7\\Desktop\\"+imageName);

			Image im = ImageIO.read(imageFile);
			return im;

		} catch (IOException e) {

			e.printStackTrace();
			return null; 

		}
	}

	@Override
	public String uploadImage(Image imageToUpload) {

		if(imageToUpload!=null){

			File imageFile = new File("C:\\nikos7\\Pictures\\image.jpg");
			try {
				ImageIO.write(toBufferedImage(imageToUpload), "jpg", imageFile);
			} catch (IOException e) {
				e.printStackTrace();
				return "Upload Failed";
			}

			return "Upload Complete";
		}

		throw new WebServiceException("Upload Failed");

	}

	/** 
	 *  Utility to convert Image to BufferedImage in order to save it to a file
	 *  From : https://code.google.com/p/game-engine-for-java/source/browse/src/com/gej/util/ImageTool.java#31
	 */
	public static BufferedImage toBufferedImage(Image img)
	{
	    if (img instanceof BufferedImage)
	    {
	        return (BufferedImage) img;
	    }

	    // Create a buffered image with transparency
	    BufferedImage bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);

	    // Draw the image on to the buffered image
	    Graphics2D bGr = bimage.createGraphics();
	    bGr.drawImage(img, 0, 0, null);
	    bGr.dispose();

	    // Return the buffered image
	    return bimage;
	}

}

There is small problem in the implmentation above. If the service returs a null value you will get the following error

Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: Method Parameter: return cannot be null. This is BP 1.1 R2211 violation.

So you have to make sure that your program never returns null. For instance, you can have a default image and return that every time something goes wrong with your program and you get an exception (a checked exception). Or you can have something like a custom Object that will include an image and also a status code, and return that Object every time.

Web Service Endpoint Publisher

ImageServerPublisher.java:

package com.javacodegeeks.enterprise.ws.jaxws;

import javax.xml.ws.Endpoint;

import com.javacodegeeks.enterprise.ws.jaxws.ImageServerImpl;

public class ImageServerPublisher{

	public static void main(String[] args) {
	   Endpoint.publish("http://localhost:9999/webservice/imageService", new ImageServerImpl());
    }

}

Now when you run the publisher the Web Service will be available to the clients, deployed in the URL:

http://localhost:9999/webservice/imageService

And this is the wsdl file that is automatically created (published in http://localhost:9999/webservice/imageService?wsdl):

WSDL:

<!-- Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is 
	JAX-WS RI 2.2.4-b01. -->
<!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is 
	JAX-WS RI 2.2.4-b01. -->
<definitions
	xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
	xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy"
	xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
	xmlns:tns="http://jaxws.ws.enterprise.javacodegeeks.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
	xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://jaxws.ws.enterprise.javacodegeeks.com/"
	name="ImageServerImplService">
	<wsp:Policy wsu:Id="ImageServerImplPortBinding_MTOM_Policy">
		<ns1:OptimizedMimeSerialization
			xmlns:ns1="http://schemas.xmlsoap.org/ws/2004/09/policy/optimizedmimeserialization"
			wsp:Optional="true" />
	</wsp:Policy>
	<types />
	<message name="downloadImage">
		<part name="arg0" type="xsd:string" />
	</message>
	<message name="downloadImageResponse">
		<part name="return" type="xsd:base64Binary" />
	</message>
	<message name="uploadImage">
		<part name="arg0" type="xsd:base64Binary" />
	</message>
	<message name="uploadImageResponse">
		<part name="return" type="xsd:string" />
	</message>
	<portType name="ImageServerInterface">
		<operation name="downloadImage">
			<input
				wsam:Action="http://jaxws.ws.enterprise.javacodegeeks.com/ImageServerInterface/downloadImageRequest"
				message="tns:downloadImage" />
			<output
				wsam:Action="http://jaxws.ws.enterprise.javacodegeeks.com/ImageServerInterface/downloadImageResponse"
				message="tns:downloadImageResponse" />
		</operation>
		<operation name="uploadImage">
			<input
				wsam:Action="http://jaxws.ws.enterprise.javacodegeeks.com/ImageServerInterface/uploadImageRequest"
				message="tns:uploadImage" />
			<output
				wsam:Action="http://jaxws.ws.enterprise.javacodegeeks.com/ImageServerInterface/uploadImageResponse"
				message="tns:uploadImageResponse" />
		</operation>
	</portType>
	<binding name="ImageServerImplPortBinding" type="tns:ImageServerInterface">
		<wsp:PolicyReference URI="#ImageServerImplPortBinding_MTOM_Policy" />
		<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
			style="rpc" />
		<operation name="downloadImage">
			<soap:operation soapAction="" />
			<input>
				<soap:body use="literal"
					namespace="http://jaxws.ws.enterprise.javacodegeeks.com/" />
			</input>
			<output>
				<soap:body use="literal"
					namespace="http://jaxws.ws.enterprise.javacodegeeks.com/" />
			</output>
		</operation>
		<operation name="uploadImage">
			<soap:operation soapAction="" />
			<input>
				<soap:body use="literal"
					namespace="http://jaxws.ws.enterprise.javacodegeeks.com/" />
			</input>
			<output>
				<soap:body use="literal"
					namespace="http://jaxws.ws.enterprise.javacodegeeks.com/" />
			</output>
		</operation>
	</binding>
	<service name="ImageServerImplService">
		<port name="ImageServerImplPort" binding="tns:ImageServerImplPortBinding">
			<soap:address location="http://localhost:9999/webservice/imageService" />
		</port>
	</service>
</definitions>

2. Web Service Client

This is client that consumes the above Web Service, written in Java:

WebServiceClient.java:

package com.javacodegeeks.enterprise.ws.client;

import java.awt.Image;
import java.io.File;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.Service;
import javax.xml.ws.soap.SOAPBinding;

import com.javacodegeeks.enterprise.ws.jaxws.ImageServerInterface;

public class WebServiceClient{

	public static void main(String[] args) throws Exception {

		URL url = new URL("http://localhost:9999/webservice/imageService?wsdl");
        QName qname = new QName("http://jaxws.ws.enterprise.javacodegeeks.com/", "ImageServerImplService");

        Service service = Service.create(url, qname);
        ImageServerInterface imageServer = service.getPort(ImageServerInterface.class);

        /********* Download ***********/
        Image image = imageServer.downloadImage("sc.jpg");

        //display the received image in a frame
        JFrame frame = new JFrame();
        frame.setSize(800, 800);
        JLabel label = new JLabel(new ImageIcon(image));
        frame.add(label);
        frame.setVisible(true);

        /********* Upload *************/
        Image imageToUpload = ImageIO.read(new File("C:\\nikos7\\Pictures\\photo.jpg"));

        //enable MTOM
        BindingProvider bindingProvider = (BindingProvider) imageServer;
        SOAPBinding sopadBinding = (SOAPBinding) bindingProvider.getBinding();
        sopadBinding.setMTOMEnabled(true);

        String serverStatus = imageServer.uploadImage(imageToUpload);
        System.out.println("Server returned Status : " + serverStatus);

    }

}

The above program reads the wsdl file of the published Web Service. In the download part, the client sends the name of the image to be downloaded to the server. The server responds with the Image and the client creats a simple JFrame to display it. In the upload part, the client reads an image from his file system and sends it to the server. On the other side, the server will simply store the image to his file system and the upload proccess is completed.

The output of the above program would be:

Server returned Status : Upload Complete

This was an example on JAX-WS Attachment With MTOM. Download the Eclipse Project of this tutorial : JAX-WS-MTOM.zip

Related Whitepaper:

Java Essential Training

Author David Gassner explores Java SE (Standard Edition), the language used to build mobile apps for Android devices, enterprise server applications, and more!

The course demonstrates how to install both Java and the Eclipse IDE and dives into the particulars of programming. The course also explains the fundamentals of Java, from creating simple variables, assigning values, and declaring methods to working with strings, arrays, and subclasses; reading and writing to text files; and implementing object oriented programming concepts. Exercise files are included with the course.

Get it Now!  

Examples Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Examples Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Examples Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close