使用Spring實現Web服務

Spring對遠程調用提供了良好支持,它支持的主要遠程調用協議有:RMI、基於HTTP的遠程調用(使用org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter實現)HessianBurlapSOAPSpring-WSWeb Services)等。因爲本章主要講述Web服務的實現方法,那麼我們就來看看SpringSOAPSpring-WS的支持。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

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

下圖顯示了客戶端的執行界面:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章