How to implement JAXWS web services using Spring and Embedded Jetty server?
Dependencies in pom.xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty</artifactId>
<version>6.1.4</version>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>6.1.4</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<!-- very important NOTE : if the app is deployed to java 1.6 enviroment, do not forget to add jaxb-api-2.1.jar into endorsed lib path to the jdk otherwise you get an exception like this : java.lang.LinkageError: JAXB 2.0 API is being loaded from the bootstrap classloader so in order to avoid this exception just put jaxb-api-2.1.jar into JAVA6_HOME/lib/endorsed for the dependencies of spring-jaxws please refer to https://jax-ws-commons.dev.java.net/spring/test-app/dependencies.html the url of the web service is :http://localhost:8080/JAXWS_SPRING/testWs-->
<dependency>
<groupId>org.jvnet.jax-ws-commons.spring</groupId>
<artifactId>jaxws-spring</artifactId>
<version>1.8</version>
</dependency>
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>avalon-framework</groupId>
<artifactId>avalon-framework</artifactId>
<version>4.1.3</version>
</dependency>
<dependency>
<groupId>com.sun.org.apache.xml.internal</groupId>
<artifactId>resolver</artifactId>
<version>20050927</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.1.2</version>
</dependency>
<dependency>
<groupId>com.sun.xml.messaging.saaj</groupId>
<artifactId>saaj-impl</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>com.sun.xml.stream</groupId>
<artifactId>sjsxp</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.stream.buffer</groupId>
<artifactId>streambuffer</artifactId>
<version>0.4</version>
</dependency>
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.1.3</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>jsr250-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>javax.jws</groupId>
<artifactId>jsr181-api</artifactId>
<version>1.0-MR1</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>javax.xml.soap</groupId>
<artifactId>saaj-api</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>javax.xml.stream</groupId>
<artifactId>stax-api</artifactId>
<version>1.0-2</version>
</dependency>
<dependency>
<groupId>javax.xml.ws</groupId>
<artifactId>jaxws-api</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>logkit</groupId>
<artifactId>logkit</artifactId>
<version>1.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.xbean</groupId>
<artifactId>xbean-spring</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.jvnet</groupId>
<artifactId>mimepull</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.jvnet.staxex</groupId>
<artifactId>stax-ex</artifactId>
<version>1.0</version>
</dependency>
Defining Jetty server in application-context.xml where spring beans are also defined
To define an embedded jetty server, connector, threadpool and handler properties have to be defined.
given below is the jetty.xml
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="Server" class="org.mortbay.jetty.Server" init-method="start" destroy-method="stop">
<property name="connectors">
<list>
<bean id="Connector" class="org.mortbay.jetty.nio.SelectChannelConnector">
<property name="port" value="8181" />
</bean>
</list>
</property>
<property name="threadPool">
<bean id="jettyThreadPool" class="org.mortbay.thread.BoundedThreadPool">
<property name="minThreads" value="5" />
<property name="maxThreads" value="10" />
</bean>
</property>
<property name="handler">
<bean id="handlers" class="org.mortbay.jetty.handler.HandlerCollection">
<property name="handlers">
<list>
<bean id="contexts" class="org.mortbay.jetty.handler.ContextHandlerCollection">
<property name="handlers">
<list>
<bean class="org.mortbay.jetty.webapp.WebAppContext">
<property name="contextPath" value="/JAXWS_SPRING" />
<property name="war" value="./WebContent" />
</bean>
</list>
</property>
</bean>
</list>
</property>
</bean>
</property>
</bean>
</beans>
The issue here is that the property defined as “war” has a value WebContent and this WebContent directory has to be in the project
and within this folder the WEB-INF folder has to be created.
The directory structure of the project has given below.
JAXWS_SPRING
–src
—-resources
——-jetty.xml
——-applicationContext.xml
WebContent
—-WEB-INF
——-web.xml
An advantage of this initialization is that you don’t have to change anything in the project if you want to deploy it to Tomcat server.
When spring is initialized jetty server starts immediately and deploys JAXWS_SPRING into jetty container as specified in the web.xml
<?xml version="1.0" encoding="ISO-8859-1"?><!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>JAXWS_SPRING</display-name>
<description>JAXWS_SPRING</description>
<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>
<servlet>
<servlet-name>jaxws-servlet</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSSpringServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>jaxws-servlet</servlet-name>
<url-pattern>/testMethod</url-pattern>
</servlet-mapping></web-app>
applicationContext.xml is where the web service is defined. During the deployment of the project,the beans in the application-context.xml are initialized.
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:ws="http://jax-ws.dev.java.net/spring/core" xmlns:wss="http://jax-ws.dev.java.net/spring/servlet" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsdhttp://jax-ws.dev.java.net/spring/core http://jax-ws.dev.java.net/spring/core.xsdhttp://jax-ws.dev.java.net/spring/servlet http://jax-ws.dev.java.net/spring/servlet.xsd">
<wss:binding url="/testMethod">
<wss:service><!-- nested bean is of course fine -->
<ws:service bean="#myService">
<ws:handlers>
<ref bean="myHandler" />
</ws:handlers>
</ws:service>
</wss:service>
</wss:binding>
<bean id="myService" class="foo.MyService">
<property name="base">
<!-- you can also use propert injection for the service class -->
<value>42</value>
</property>
</bean>
<bean id="myHandler" class="foo.MyHandler" />
</beans>