Implementing Web Services with Spring and Axis

Bookmark and Share
In the past, I wrote a post on how to implement Web Services using JAX-WS on Glassfish, and Apache Axis. In this post I will describe how to implement Web Services using the Spring framework and Apache Axis. The spring framework uses JAX-RPC API to help implement and access SOAP-WSDL based Web Services. The main components required for implementing and accessing Web Services in Spring are:
  • JaxRpcPortProxyFactoryBean: This is a proxy factory for proxies that communicate with backend Web Services.
  • ServletEndPointSupport: This is the base class for Web Service End Points. A Web Service end point is a class that will be exposed as a Web Service.

Creating the Web Service

The example contains a simple Web Service that echoes back the request message to the client. Follow these steps to imlement the Web Service

  1. Start with a dynamic web project in Eclipse.
  2. The Service Interface: The following is the code for the Service Interface. Nothing new here.
    package service;
    
    public interface ISpringWS {
    
    public String sayHello(String message);
    
    }
    ISpringWS.java
  3. The Service Implementation: The following is the code for the Service Implementation. Again, it's a simple POJO.
    package service;
    
    public class SpringWS implements ISpringWS {
    
    public String sayHello(String message) {
    System.out.println("sayHello:" + message);
    return "You said '" + message + "'";
    }
    }
    SpringWS.java
  4. The Service Endpoint: Here is the code for the Service Endpoint, followed by an explanation
    package service;
    
    import org.springframework.remoting.jaxrpc.ServletEndpointSupport;
    
    public class SpringWSEndPoint extends ServletEndpointSupport implements ISpringWS {
    private ISpringWS springWS;
    
    protected void onInit() {
    this.springWS = (ISpringWS) getWebApplicationContext().getBean("springWS");
    }
    
    public String sayHello(String message) {
    return springWS.sayHello(message);
    }
    }
    SpringWSEndPoint.java

    To implement Web Services using the Spring framework, a service endpoint class has to be written for each service. The service endpoint generally delegates the requests to the Spring-managed beans which implement the actual web service. The service endpoint, however, is not managed by Spring, but by the Web Service too (Axis in our case). Also note that the Service Endpoint implements the Service Interface, since this class acts is the interface to the Web Service.
  5. The server configuration: In order to use Axis as the deployment tool for the web service, you have to add a service section to the Axis server-config.wsdd file. Here is the file in full.
    <?xml version="1.0" encoding="UTF-8"?>
    <deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
    <globalConfiguration>
    <parameter name="adminPassword" value="admin" />
    <parameter name="sendXsiTypes" value="true" />
    <parameter name="sendMultiRefs" value="true" />
    <parameter name="sendXMLDeclaration" value="true" />
    <parameter name="axis.sendMinimizedElements" value="true" />
    <requestFlow>
    <handler type="java:org.apache.axis.handlers.JWSHandler">
    <parameter name="scope" value="session" />
    </handler>
    <handler type="java:org.apache.axis.handlers.JWSHandler">
    <parameter name="scope" value="request" />
    <parameter name="extension" value=".jwr" />
    </handler>
    </requestFlow>
    </globalConfiguration>
    <handler name="Authenticate" type="java:org.apache.axis.handlers.SimpleAuthenticationHandler" />
    <handler name="LocalResponder" type="java:org.apache.axis.transport.local.LocalResponder" />
    <handler name="URLMapper" type="java:org.apache.axis.handlers.http.URLMapper" />
    <service name="AdminService" provider="java:MSG">
    <parameter name="allowedMethods" value="AdminService" />
    <parameter name="enableRemoteAdmin" value="false" />
    <parameter name="className" value="org.apache.axis.utils.Admin" />
    <namespace>http://xml.apache.org/axis/wsdd/</namespace>
    </service>
    <service name="SpringWS" provider="java:RPC">
      <parameter name="allowedMethods" value="*" />
      <parameter name="className" value="service.SpringWSEndPoint" />
    </service>
    <service name="Version" provider="java:RPC">
      <parameter name="allowedMethods" value="getVersion" />
      <parameter name="className" value="org.apache.axis.Version" />
    </service>
    <transport name="http">
    <requestFlow>
    <handler type="URLMapper" />
    <handler type="java:org.apache.axis.handlers.http.HTTPAuthHandler" />
    </requestFlow>
    </transport>
    <transport name="local">
    <responseFlow>
    <handler type="LocalResponder" />
    </responseFlow>
    </transport>
    </deployment>
    WEB-INF/server-config.wsdd
  6. The spring application context: Here is the applicationContext.xml used for the example
    <?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="springWSEndpoint" class="service.SpringWSEndPoint"></bean>
    <bean id="springWS" class="service.SpringWS"></bean>
    </beans>
    WEB-INF/applicationContext.xml
  7. The Web deployment descriptor
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>WSSpring</display-name>
    <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
    
    <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    
    <servlet>
      <servlet-name>axis</servlet-name>
      <servlet-class>org.apache.axis.transport.http.AxisServlet</servlet-class>
      <load-on-startup>5</load-on-startup>
    </servlet>
    <servlet-mapping>
      <servlet-name>axis</servlet-name>
      <url-pattern>/axis/*</url-pattern>
    </servlet-mapping>
    </web-app>
    WEB-INF/web.xml
    The Axis servlet definition enables the Axis servlet to make the service available under the given port name.
  8. Jar files: Here is a list of the jar files used for this example
    axis.jarAvailable for download at Apache Axis website
    commons-discovery.jarAvailable with the Spring framework with dependencies download.
    commons-logging.jarAvailable with the Spring framework with dependencies download.
    jaxrpc.jarAvailable with the Spring framework with dependencies download.
    log4j-1.2.13.jarAvailable with the Spring framework with dependencies download.
    saaj.jarAvailable with the Spring framework with dependencies download.
    spring.jarNo need to say where.
    wsdl4j-1.5.1.jarAvailable with the Spring framework with dependencies download.
  9. Deploy and Test: Deploy the application in Weblogic 9.2. You can test the service at the URL
    http://localhost:7001/WSSpring/axis/SpringWS?wsdl

The Web Service Client
  1. Start with a dynamic web project in Eclipse and include all the above jar files.
  2. Service Interface: The service interface can be generated using any of the tools that create Java classes using the WSDL file. For this example, simply copy the ISpringWS.java file into the client application.
    package service;
    
    public interface ISpringWS {
    
    public String sayHello(String message);
    
    }
    ISpringWS.java
  3. The client: The client is a simple Java class, with the service as a member. This will be injected by the spring framework.
    package client;
    
    import service.ISpringWS;
    
    public class SpringWSClient {
    ISpringWS springWS;
    
    public String callService() {
    return springWS.sayHello("Hello");
    }
    
    public ISpringWS getSpringWS() {
    return springWS;
    }
    
    public void setSpringWS(ISpringWS springWS) {
    this.springWS = springWS;
    }
    
    }
    SpringWSClient.java
  4. The Client Servlet:
    package servlets;
    
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import org.springframework.web.context.WebApplicationContext;
    import org.springframework.web.context.support.WebApplicationContextUtils;
    import client.SpringWSClient;
    
    public class WSSpringClientServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
    
    public WSSpringClientServlet() {
    super();
    }
    
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(this.getServletContext());
      SpringWSClient sender = (SpringWSClient) ctx.getBean("springWSClient");
    String result = sender.callService();
    response.getWriter().println(result);
    response.getWriter().close();
    }
    }
    WSSpringClientServlet.java
  5. The Application context: You can see the definition of the JaxRpcPortProxyFactoryBean here. This class was described briefly earlier in the post.
    <?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="jaxRpcProxy" class="org.springframework.remoting.jaxrpc.JaxRpcPortProxyFactoryBean">
      <property name="serviceFactoryClass">
        <value>org.apache.axis.client.ServiceFactory</value>
      </property>
      <property name="wsdlDocumentUrl">
        <value>http://localhost:7001/WSSpring/axis/SpringWS?wsdl</value>
      </property>
      <property name="namespaceUri">
        <value>http://localhost:7001/WSSpring/axis/SpringWS</value>
      </property>
      <property name="serviceName">
        <value>SpringWSEndPointService</value>
      </property>
      <property name="portName">
        <value>SpringWS</value>
      </property>
      <property name="serviceInterface">
        <value>service.ISpringWS</value>
      </property>
    
    </bean>
    <bean id="springWSClient" class="client.SpringWSClient">
    <property name="springWS" ref="jaxRpcProxy" />
    </bean>
    
    </beans>
    WEB-INF/applicationContext.xml

    The service interface used here is a plain Java interface. Using the definition this way will turn service invocations into dynamic JAX-RPC calls (using JAX-RPC's Dynamic Invocation Interface). Another way to implement this is to have the Service interface extend java.rmi.Remote, and have a definition of portInterface.
  6. The web deployment descriptor:
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>WSSpringClient</display-name>
    
    <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <servlet>
    <description></description>
    <display-name>WSSpringClientServlet</display-name>
    <servlet-name>WSSpringClientServlet</servlet-name>
    <servlet-class>servlets.WSSpringClientServlet</servlet-class>
    </servlet>
    <servlet-mapping>
    <servlet-name>WSSpringClientServlet</servlet-name>
    <url-pattern>/WSSpringClientServlet</url-pattern>
    </servlet-mapping>
    
    
    <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    
    </welcome-file-list>
    </web-app>
    WEB-INF/web.xml

{ 0 comments... Views All / Send Comment! }

Post a Comment