Recently I had to port an existing web service (that is running on Glassfish) to tomcat while using Spring and Maven.
The resources I found online here, here and here are very helpful. But I had few hiccups in running the sample application I downloaded from the links. Hence this version with all workarounds and fixes, which I can refer back in the future if needed.
The best approach to understand this tutorial is, to download the application source first (available under Download section), build it, run the application and then go through the tutorial.
Jdk 1.6 (or) Higher & Maven (2.2.x). Thats all? yes thats all you need to have in your computer. Let us just configure all application dependencies in Maven configuration file (pom.xml) and let the Maven take care of pulling them from internet central repository when we compile the application.
Maven – Build tool, Spring – for dependency injection & bean configuration, Jax-Ws Commons Spring extension, Jetty – Embedded server
Run below maven command to create a typical java web application project structure.
mvn archetype:generate -DarchetypeArtifactId=maven-archetype-webapp -DgroupId=com.bdot -DartifactId=jaxws-spring-server -DinteractiveMode=false
Once project structure is created, create IDE specific project files using below command.
mvn idea:idea --> for Intellij Idea users
mvn eclipse:eclipse --> for eclipse users
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
@WebService()
@SOAPBinding(style = SOAPBinding.Style.RPC, use = SOAPBinding.Use.LITERAL)
public class UserOperationService {
private static final String HELLO = "Hello";
@WebMethod(operationName = "sayHello")
public String sayHelloToTheUser(@WebParam(name = "name") String userName) {
return HELLO + " " + userName;
}
}
Add spring dependencies to pom.xml.
Note:- ${spring.version} is added as a property in pom.xml, Take a look at the pom.xml in the downloaded application
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
And spring listener to the web.xml
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Jax-WS Spring Server Web Application</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
Before we configure our web service in spring applicationcontext.xml, we need various JAX-WS commons dependencies. So lets update our pom.xml as shown below. Note:- As we already added Spring dependencies already to the pom.xml, Let us exclude them from jax-ws commons.
<dependency>
<groupId>org.jvnet.jax-ws-commons.spring</groupId>
<artifactId>jaxws-spring</artifactId>
<version>1.8</version>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
</exclusions>
</dependency>
applicationContext.xml configuration. This instructs Spring to deligate the any web service call with mapping “webservice/user-service” to UserOperationService.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:ws="http://jax-ws.dev.java.net/spring/core"
xmlns:wss="http://jax-ws.dev.java.net/spring/servlet"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://jax-ws.dev.java.net/spring/core http://jax-ws.dev.java.net/spring/core.xsd
http://jax-ws.dev.java.net/spring/servlet http://jax-ws.dev.java.net/spring/servlet.xsd"
default-autowire="byName">
<!-- Tell spring that we may be using Annotations also -->
<context:annotation-config/>
<wss:binding url="/webservice/user-service">
<wss:service>
<ws:service bean="#userOperationService">
</ws:service>
</wss:service>
</wss:binding>
<bean id="userOperationService" class="com.bdot.ws.UserOperationService"/>
</beans>
Cool, we have created our web service and configured spring. But How to divert the incoming URL requests to Spring? Adding below shown servlet mapping in the web.xml does the magic!
<servlet>
<servlet-name>jaxws-servlet</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSSpringServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jaxws-servlet</servlet-name>
<url-pattern>/webservice/*</url-pattern>
</servlet-mapping>
Many of the dependencies we added implicitly download the javax.activation java library. But javax.activation is available in Java 1.6 by default, which causes the linkage errors by class loader. So, we may have to exclude javax.activation from all our dependencies. Please take a look at the pom.xml in the downloaded application.
Aah finally, Building the application is very easy. Just extract the application downloaded and go to the application folder (where you can see pom.xml) from command prompt, and run below maven command. First run may take a while as maven tries to download all dependencies from central repository.
mvn clean install
“Build is successful”. Now let us run the application with the following command
mvn jetty:run
Hurray. Lets see the application we built, Go to your favourite browser and access the WSDL generated @
http://localhost:9999/webservice/user-service?wsdl
You can use either SOAP UI or any other simple client application to consume the web service.
Source, pick it up from Bitbucket here
or to download click here
Maven Installation / Environment Setup
Below are the links that helped me understanding how to develop this application.
JAX-WS Commons
j2eeroad blog
SpringJaxWsApp