使用Spring实现Web服务

Spring对远程调用提供了良好支持,它支持的主要远程调用协议有:RMI、基于HTTP的远程调用(使用org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter实现)HessianBurlapSOAPSpring-WSWeb Services)等。因为本章主要讲述Web服务的实现方法,那么我们就来看看SpringSOAPSpring-WS的支持。

Spring-WS之基础

Spring-WS可以从Spring网站单独下载,它不包含在Spring核心包中。Spring-WS支持契约最先式的Web服务开发方法。因此,要在Spring中开发Web服务,开发者首先要准备好Web服务契约,即WSDL文件,这对每位开发者来说,并不是一件非常容易的事,尤其对那些不能手动创建WSDL的开发者来说更是如此。在这种情况下,另一种可选方法是使用工具先创建WSDL,然后使用Spring-WS来实现Web服务。

我们在前面已经学习过,如何使用Axis开发Web服务。现在,我们需要利用Spring的以下特性来实现Web服务:

1) 依赖注入

2)  对象交织(Object Wiring,即把对象连接在一起以便它们相互之间能够通信)

前面我们提到,我们还需要一个生成WSDL的工具,为了使Spring开发Web服务的过程更加简单直接,我们可以使用一种混合的方法,即使用Axis+Spring来实现Web服务,这样,我们可充分利用它们的长处。下面,我们看一下其具体实现过程。

使用Spring实现Web服务

因为我们前面已经学习了如何部署基于AxisWeb服务,因此,我们可以以前面例子的为基础,将它集成到Spring中。Spring提供了一个名为org.springframework.remoting.jaxrpc.ServletEndpointSupportServlet,它是JAX-RPC Servlet的基类,我们可以使用它非常方便地实现Web服务,这个类还包含了当前Spring应用上下文的引用,因此我们能够对Spring中的Java Bean进行查找或加载资源等操作。

服务器端和客户端代码

我们将使用前面Axis例子的代码略加改动,来实现服务器端。因此,本节代码和上节有所重复,您可以在本书源代码的ch03/03_Spring/WebService/src目录中找到服务器端代码。

IHello.java

IHello是一个非常简单的业务接口,它只有一个hello方法。因为我们想把该接口和客户端共享,所以我们把它放到一个共用的单独目录(ch03/03_Spring/Common/src)中。

  1. public interface IHello {
  2.     String hello(String param);
  3. }

IHelloWeb.java

IHelloWeb接口和IHello接口不同,它是我们的Web服务接口,我们只从该接口生成WSDL契约。

public interface IHelloWeb extends IHello{

}

HelloWebService.java

与前面的Axis例子不同,这里的HelloWebService继承自ServletEndpointSupport,因此,我们可以在这个类中得到当前Spring应用上下文的引用。

  1. public class HelloWebService extends ServletEndpointSupport implements
  2.         IHelloWeb {
  3.     private IHello iHello;
  4.     public HelloWebService() {
  5.         System.out.println("Inside HelloWebService.HelloWebService...");
  6.     }
  7.     protected void onInit() {
  8.         System.out.println("Inside HelloWebService.onInit...");
  9.         this.iHello = (IHello) getWebApplicationContext().getBean("hello");
  10.     }
  11.     public void setHello(IHello iHello) {
  12.         this.iHello = iHello;
  13.     }
  14.     public String hello(String param) {
  15.         System.out.println("Inside HelloWebService.hello...");
  16.         return iHello.hello(param);
  17.     }
  18. }

在上面的onInit方法中,我们得到Spring上下文,根据bean的名字”hello”得到SpringJava Bean,这个bean是另一个业务bean的引用,该业务bean的实现代码解释如下。

Hello.java

Hello是一个Spring bean,其配置见applicationContext.xml文件,该bean实现了业务方法。

  1. public class Hello implements IHello {
  2.     public Hello() {
  3.         System.out.println("Inside Hello.Hello...");
  4.     }
  5.     public String hello(String param) {
  6.         System.out.println("Inside Hello.hello...");
  7.         return "Hello " + param;
  8.     }
  9. }

applicationContext.xml

applicationContext.xml文件位于ch03/03_Spring/WebService/config文件夹中,这个文件定义了所有的Spring bean

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
  3. <beans>
  4.     <bean id="hello" class="com.binildas.apache.axis.AxisSpring.Hello">
  5.     </bean>
  6. </beans>

web.xml

web.xml位于ch03/03_Spring/WebService/config目录,它演示了如何在当前Web应用上下文中嵌入Spring上下文。但我们对Web档案进行打包时,我们需要将applicationContext.xml 放到web.xml中定义的路径中(/WEB-INF/)

  1. <?xml version="1.0" encoding="ISO-8859-1"?>
  2. <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web
  3. Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
  4. <web-app>
  5.     <listener>
  6.         <listener-class>
  7.             org.springframework.web.context.ContextLoaderListener
  8. </listener-class>
  9.     </listener>
  10.     <context-param>
  11.         <param-name>contextConfigLocation</param-name>
  12.         <param-value>
  13.             /WEB-INF/applicationContext.xml
  14. </param-value>
  15.     </context-param>
  16.     <servlet>
  17.         <servlet-name>AxisServlet</servlet-name>
  18.         <display-name>Apache-Axis Servlet</display-name>
  19.         <servlet-class>
  20.             org.apache.axis.transport.http.AxisServlet
  21. </servlet-class>
  22.         <load-on-startup>1</load-on-startup>
  23.     </servlet>
  24.     <servlet-mapping>
  25.         <servlet-name>AxisServlet</servlet-name>
  26.         <url-pattern>/services/*</url-pattern>
  27.     </servlet-mapping>
  28. </web-app>

Client.java

在客户端代码中,我们也简单地应用了Spring,请阅读下面的代码,看看它是如何实现的。

  1. public class Client {
  2.     private ApplicationContext ctx;
  3.     private ClientObject clientObject;
  4.     public Client() {
  5.         String[] paths = { "/applicationContextClient.xml" };
  6.         ctx = new ClassPathXmlApplicationContext(paths);
  7.         clientObject = (ClientObject) ctx.getBean("clientObject");
  8.     }
  9.     public void finalize() throws Throwable {
  10.         super.finalize();
  11.         clientObject = null;
  12.         ctx = null;
  13.     }
  14.     private void test1() {
  15.         log(clientObject.hello("Binil"));
  16.     }
  17.     public static void main(String[] args) throws Exception {
  18.         Client client = new Client();
  19.         client.test1();
  20.     }
  21. }

上面的 Client类中使用了另一个Spring bean,即ClientObject,这个bean配置详见applicationContextClient.xml

ClientObject.java

ClientObject只是一个辅助bean,其源码如下:

  1. public class ClientObject {
  2.     private IHello helloService;
  3.     public void setHelloService(IHello helloService) {
  4.         this.helloService = helloService;
  5.     }
  6.     public String hello(String param) {
  7.         return helloService.hello(param);
  8.     }
  9. }

在上面的代码中,我们将远程服务的代理注入到该bean中,因此,所有的调用将被委派到Web服务,服务代理的配置参见applicationContextClient.xml

applicationContextClient.xml文件中,我们不但配置一个ClientObjectSpring bean,而且还配置了一个远程Web服务的代理bean。为了配置服务代理,您需要定义JaxRpcPortProxyFactoryBean,从而该代理将实现远程接口。因为我们使用Axis实现了基于SpringWeb服务,我们可只使用Axis本身作为客户端,调用Web服务。因此,您必须指定org.apache.axis.client.ServiceFactory 作为服务工厂类。然后,您还需要为JaxRpcPortProxyFactoryBean定义一些其它的参数,它们显示如下:

 

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
  3. "http://www.springframework.org/dtd/spring-beans.dtd">
  4. <beans>
  5.     <bean id="helloService"
  6.         class="org.springframework.remoting.jaxrpc.JaxRpcPortProxyFactoryBean">
  7.         <property name="serviceFactoryClass">
  8.             <value>org.apache.axis.client.ServiceFactory</value>
  9.         </property>
  10.         <property name="serviceInterface" value="com.binildas.apache.axis.AxisSpring.IHello" />
  11.         <property name="wsdlDocumentUrl"
  12.             value="http://localhost:8080/AxisSpring/
  13. services/HelloWebService?wsdl" />
  14.         <property name="namespaceUri" value="http://AxisSpring.axis.apache.binildas.com" />
  15.         <property name="serviceName" value="IHelloWebService" />
  16.         <property name="portName" value="HelloWebService" />
  17.     </bean>
  18.     <bean id="clientObject" class="com.binildas.apache.axis.AxisSpring.ClientObject">
  19.         <property name="helloService" ref="helloService" />
  20.     </bean>
  21. </beans>

运行服务器端和客户端

要编译服务器端代码,请执行下面命令:

 cd ch03/03_Spring
ant

上面的命令将编译服务器端和客户端代码,编译完成后,我们可在下面的目录中找到一个可部署的Web归档文件(AxisSpring.war)

ch03/03_Spring/WebService/dist

现在,您就可以把这个war文件拷贝到您的Web服务器的Webapps目录,然后,重启服务器。如果部署没有问题,您就可以访问http://localhost:8080/AxisSpring/services/HelloWebService?wsdl获取该Web服务的WSDL

接下来您就可以执行客户端代码测试您的Web服务,要执行客户端代码,请使用下列命令:

cd ch03/03_Spring
ant run

下图显示了客户端的执行界面:

使用Spring实现Web服务_第1张图片

你可能感兴趣的:(spring,bean,servlet,服务器,web服务,encoding)