Send Any File using SOAP Webservice

Introduction

This tutorial shows how we can send file using SOAP based webservice. The type of the file can be anything, i.e., text, image, pdf, MS doc etc. For this type of application we need to create two applications – one will work as a client application(which sends a file) and other one will work as a server application(which receives a file). So the server application will deploy the service whereas client application will consume the service. In server application we will have logic for what will be done with the file content after receiving the file. Using the client application we will upload the file and send through the SOAP service.

In this example both client and server applications are web based maven application. In client application we will upload the file using JSP, Servlet and send it to the server application which then saves the received file to the specific location on disk.

In this post we will use wsgen and wsimport through maven plugin to generate WSDL and stubs from WSDL, respectively.

Final Results

Home page

SOAP File Attachment

When no file selected for upload

SOAP File Attachment

When a file is selected and sent

SOAP File Attachment

Prerequisites

Eclipse Neon, Tomcat 8.5.39, JDK 1.8, maven 3.6.0

Example with Source Code

We will now look at the server and client applications how they get created.

Server Application

Creating Project

Create a maven based web application in Eclipse with the below group and artifact id:

Group Id: com.jeejava, Artifact Id: soap-send-file

The project structure will look similar to the below image:

send any file using soap webservice

Updating Build File

Update the default pom.xml file with the following content in order to include required dependencies for JAX-WS and wsgen command in jaxws maven plugin.

wsgen in jaxws maven plugin is used here to generate WSDL file for the SOAP webservice.

You can also use wsgen in jaxws command using cmd prompt if you do not want to use wsgen in jaxws maven plugin.

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.jeejava</groupId>
	<artifactId>soap-send-file</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>

	<url>http://maven.apache.org</url>

	<dependencies>
		<dependency>
			<groupId>javax.xml.ws</groupId>
			<artifactId>jaxws-api</artifactId>
			<version>2.3.1</version>
		</dependency>
		<dependency>
			<groupId>com.sun.xml.ws</groupId>
			<artifactId>jaxws-rt</artifactId>
			<version>2.3.2</version>
		</dependency>
	</dependencies>

	<build>
		<finalName>soap-send-file</finalName>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.codehaus.mojo</groupId>
				<artifactId>jaxws-maven-plugin</artifactId>
				<version>2.5</version>
				<executions>
					<execution>
						<id>generate-wsdl</id>
						<phase>process-classes</phase>
						<goals>
							<goal>wsgen</goal>
						</goals>
						<configuration>
							<sei>com.jeejava.soap.service.impl.FileSendServiceImpl</sei>
							<genWsdl>true</genWsdl>
						</configuration>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</project>

Creating Service Endpoint Interface

Create endpoint interface with the below source code. In the below service endpoint interface we have only one method annotated with @WebMethod.

package com.jeejava.soap.service;

import javax.jws.WebMethod;
import javax.jws.WebService;

@WebService
public interface FileSendService {

	@WebMethod
	String sendFile(byte[] fileContent, String fileName);

}

Creating Endpoint Implementation

Create endpoint implementation for the above endpoint service. This endpoint implementation class will implement the business logic for the sendFile() method.

package com.jeejava.soap.service.impl;

import javax.jws.WebService;

import com.jeejava.soap.service.FileSendService;
import com.jeejava.soap.service.util.FileUtils;

@WebService(endpointInterface = "com.jeejava.soap.service.FileSendService")
public class FileSendServiceImpl implements FileSendService {

	@Override
	public String sendFile(byte[] fileContent, String fileName) {
		boolean response = FileUtils.saveFile(fileContent, fileName);

		if (response) {
			return "File successfully received and saved to disk!";
		}

		return "OOPs! some error occurred.";
	}

}

Creating Utility Class

We have used a utility class in the above endpoint implementation class. So we will see the corresponding utility class that does some utility operations.

package com.jeejava.soap.service.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public final class FileUtils {

	private FileUtils() {
	}

	public static boolean saveFile(byte[] fileContent, String fileName) {
		OutputStream outputStream = null;

		try {
			File file = new File("C:/workspace" + File.separator + fileName);
			outputStream = new FileOutputStream(file);
			outputStream.write(fileContent);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (outputStream != null) {
				try {
					outputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

		return false;
	}

}

Defining Endpoint Pattern

Create sun-jaxws.xml file with the below content and put it under WEB-INF directory. This file defines the endpoint pattern at which the WSDL file can be accessed.

<?xml version="1.0" encoding="UTF-8"?>
<endpoints
	xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0">
	<endpoint name="SoapFileSend"
		implementation="com.jeejava.soap.service.impl.FileSendServiceImpl"
		url-pattern="/SoapFileSend" />
</endpoints>

Updating Deployment Descriptor

Modify web.xml file as below to have the servlet mapping using JAX-WS API. The JAX-WS servlet maps the endpoint URL pattern.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
          http://java.sun.com/xml/ns/javaee/web-app_3_1.xsd"
	version="3.1">

	<display-name>soap-send-file</display-name>

	<listener>
		<listener-class>
			com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
	</listener>

	<servlet>
		<servlet-name>SoapFileSend</servlet-name>
		<servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
	</servlet>

	<servlet-mapping>
		<servlet-name>SoapFileSend</servlet-name>
		<url-pattern>/SoapFileSend</url-pattern>
	</servlet-mapping>
</web-app>

Enough coding! Let’s test our application on Tomcat server.

Building the Application

Build the application either from cmd prompt using mvn clean install or from the Eclipse option Run As -> Maven install.

The build should be successful with war and WSDL files generated.

Testing the Application

Now run the application by deploying on Tomcat server. Hit the URL http://<host>:<port>/<context path>/<URL pattern>?wsdl, i.e., http://localhost:8080/soap-send-file/SoapFileSend?wsdl. You will get the below wsdl file in the browser:

send any file soap webservice

Client Application

Now we will see how we can consume the service and send file to the above application.

Creating Project

Create a maven based web project in Eclipse with the following group and artifact id.

Group Id: com.jeejava, Artifact Id: upload-file

The project structure may look similar to the below image:

soap send any file

Updating Build File

Update the pom.xml file to use required dependencies.

We have included servlet, jstl dependencies as we are working on web application for using servlet and jsp pages.

We have used wsimport in jaxws maven plugin to generate stubs from the WSDL file. We have used here URL for WSDL, if you want you may use WSDL local file as well. For that you have to uncomment the WSDL location with file name.

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.jeejava</groupId>
	<artifactId>upload-file</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<url>http://maven.apache.org</url>

	<dependencies>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.0.1</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>
	</dependencies>

	<build>
		<finalName>upload-file</finalName>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.codehaus.mojo</groupId>
				<artifactId>jaxws-maven-plugin</artifactId>
				<version>2.5</version>
				<executions>
					<execution>
						<id>generate-stubs</id>
						<phase>generate-sources</phase>
						<goals>
							<goal>wsimport</goal>
						</goals>
						<configuration>
							<!-- using wsdl from an url -->
							<wsdlUrls>
								<wsdlLocation>http://localhost:8080/soap-send-file/SoapFileSend?wsdl</wsdlLocation>
							</wsdlUrls>
							<!-- or using wsdls file directory -->
							<!-- <wsdlDirectory>src/wsdl</wsdlDirectory> -->
							<!-- which wsdl file -->
							<!-- <wsdlFiles> -->
							<!-- <wsdlFile>myWSDL.wsdl</wsdlFile> -->
							<!--</wsdlFiles> -->
							<!-- Keep generated files -->
							<keep>true</keep>
							<!-- Package name -->
							<packageName>com.jeejava.soap.stubs</packageName>
							<!-- generated source files destination -->
							<sourceDestDir>${basedir}/target/generated-classes</sourceDestDir>
						</configuration>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</project>

Building the Application

Build the application either from cmd prompt using mvn clean install or from the Eclipse option Run As -> Maven install.

The stub should be generated and build should be successful.

Updating Deployment Descriptor

Modify the deployment descriptor file – web.xml as follows. We won’t put any entry for servlet in this file because we are using servlet 3 so using annotation is enough.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
          http://java.sun.com/xml/ns/javaee/web-app_3_1.xsd"
	version="3.1">

	<display-name>Session Expiry Warning Message</display-name>

	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
</web-app>

Creating View File

Now create a view – index.jsp which will give user an opportunity to upload a file for sending using SOAP webservice.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Upload and Send File using SOAP Webservice - Servlet
	Example</title>
</head>
<body>
	<div style="width: 600px;">
		<c:if test="${!empty error}">
			<p style="color: red;">
				<c:out value="${error}" />
			</p>
		</c:if>
		<c:if test="${!empty success}">
			<p style="color: green;">
				<c:out value="${success}" />
			</p>
		</c:if>
		<form method="post" action="Upload" enctype="multipart/form-data">
			<fieldset>
				<legend>Upload File</legend>
				<p>
					<label>Select File</label><br /> <input type="file" name="file"
						id="file" />
				</p>
				<p>
					<input type="submit" name="uploadFile" value="Upload File" />
				</p>
			</fieldset>
		</form>
	</div>
</body>
</html>

Creating Utility Class

Create FileUtil.java file which holds some utility methods.

package com.jeejava.upload.utils;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;

import javax.servlet.http.Part;

public final class FileUtil {

	private FileUtil() {
	}

	public static String getFilename(Part part) {
		for (String cd : part.getHeader("content-disposition").split(";")) {
			if (cd.trim().startsWith("filename")) {
				String filename = cd.substring(cd.indexOf('=') + 1).trim().replace("\"", "");
				return filename.substring(filename.lastIndexOf('/') + 1).substring(filename.lastIndexOf('\\') + 1); // MSIE
																													// fix.
			}
		}
		return null;
	}

	public static byte[] getFileContent(InputStream inputStream) {
		try {

			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			int reads = inputStream.read();

			while (reads != -1) {
				baos.write(reads);
				reads = inputStream.read();
			}

			return baos.toByteArray();

		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (inputStream != null) {
				try {
					inputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return null;
	}

}

Creating Servlet

Create a servlet which will upload the file and send to the server application using SOAP service.

package com.jeejava.upload.servlet;

import java.io.IOException;
import java.io.InputStream;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;

import com.jeejava.soap.stubs.FileSendService;
import com.jeejava.soap.stubs.FileSendServiceImplService;
import com.jeejava.upload.utils.FileUtil;

/**
 * Servlet implementation class UploadServlet
 */
@WebServlet("/Upload")
@MultipartConfig
public class UploadServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public UploadServlet() {
		super();
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		Part filePart = request.getPart("file");
		String uploadSubmit = request.getParameter("uploadFile");
		String fileName = FileUtil.getFilename(filePart);

		if (uploadSubmit != null && fileName != null && fileName.length() > 0) {
			InputStream inputStream = filePart.getInputStream();
			byte[] fileContent = FileUtil.getFileContent(inputStream);
			FileSendServiceImplService service = new FileSendServiceImplService();
			FileSendService fileSendService = service.getFileSendServiceImplPort();
			String resp = fileSendService.sendFile(fileContent, fileName);
			if (!resp.contains("OOPs")) {
				request.setAttribute("success", resp);
			} else {
				request.setAttribute("error", resp);
			}
		} else {
			String msg = "OOPs! You must select a file to upload.";
			request.setAttribute("error", msg);
		}

		RequestDispatcher requestDispatcher = request.getRequestDispatcher("/index.jsp");
		requestDispatcher.forward(request, response);

	}
}

Testing the Application

Now run the application by deploying on Tomcat server. Hit the URL http://localhost:8080/upload-file/ to upload file and see the results as you have seen in Final Results section.

Note:  Please run the server application first in order to receive and save the file onto disk.

Source Code

You can download source code.

Thanks for reading.

Send Any File using SOAP Webservice

4 thoughts on “Send Any File using SOAP Webservice

  1. Hello Soumitra,

    I am trying to replicate the same which you mentioned above. I am facing two issues

    1. In server project: (soap-send-file)
    I am unable to go further step 8. When I execute the command line, there is no error and I don’t see any wsdl file generated.

    2. In Client project(upload-file)
    – UploadServlet has some service method(getFileSendServiceImplPort) which does not defined.

    FileSendService fileSendService = service
    .getFileSendServiceImplPort();

    Please help me.
    Thanks in advance.

      1. Hey , I have the same problem , I can’t go beyond step 8 , please help me . Here’s the error I got on my console :
        {
        com.sun.xml.ws.transport.http.servlet.WSServletDelegate doGet

        GRAVE: caught throwable

        java.lang.NoSuchMethodError: com.sun.xml.stream.writers.XMLStreamWriterImpl.setOutput(javax.xml.transform.stream.StreamResult, java.lang.String)

        at com.sun.xml.ws.api.streaming.XMLStreamWriterFactory$Zephyr$1.run(XMLStreamWriterFactory.java:321)

        at com.sun.xml.ws.api.streaming.XMLStreamWriterFactory$Zephyr$1.run(XMLStreamWriterFactory.java:314)

        at java.security.AccessController.doPrivileged(Native Method)

        at com.sun.xml.ws.api.streaming.XMLStreamWriterFactory$Zephyr.getMethod(XMLStreamWriterFactory.java:313)

        at com.sun.xml.ws.api.streaming.XMLStreamWriterFactory$Zephyr.(XMLStreamWriterFactory.java:308)

        at com.sun.xml.ws.api.streaming.XMLStreamWriterFactory$Zephyr.(XMLStreamWriterFactory.java:284)

        at com.sun.xml.ws.api.streaming.XMLStreamWriterFactory$1.initialValue(XMLStreamWriterFactory.java:108)

        at com.sun.xml.ws.api.streaming.XMLStreamWriterFactory$1.initialValue(XMLStreamWriterFactory.java:84)

        at com.sun.xml.ws.api.streaming.ContextClassloaderLocal.createNewInstance(ContextClassloaderLocal.java:74)

        at com.sun.xml.ws.api.streaming.ContextClassloaderLocal.get(ContextClassloaderLocal.java:60)

        at com.sun.xml.ws.api.streaming.XMLStreamWriterFactory.get(XMLStreamWriterFactory.java:191)

        at com.sun.xml.ws.api.streaming.XMLStreamWriterFactory.create(XMLStreamWriterFactory.java:215)

        at com.sun.xml.ws.server.SDDocumentImpl.writeTo(SDDocumentImpl.java:286)

        at com.sun.xml.ws.transport.http.HttpAdapter.publishWSDL(HttpAdapter.java:931)

        at com.sun.xml.ws.transport.http.HttpAdapter.handleGet(HttpAdapter.java:440)

        at com.sun.xml.ws.transport.http.servlet.ServletAdapter.invokeAsync(ServletAdapter.java:193)

        at com.sun.xml.ws.transport.http.servlet.WSServletDelegate.doGet(WSServletDelegate.java:161)

        at com.sun.xml.ws.transport.http.servlet.WSServlet.doGet(WSServlet.java:89)

        at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)

        at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)

        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)

        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)

        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)

        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)

        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)

        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)

        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)

        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)

        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)

        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)

        at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:668)

        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)

        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)

        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)

        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)

        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:791)

        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1417)

        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)

        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)

        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)

        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)

        at java.lang.Thread.run(Thread.java:748)
        }

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to top