1. 程式人生 > >使用Spring WS 2.0開發基於SOAP的web service

使用Spring WS 2.0開發基於SOAP的web service

經過1年的開發之後,SpringWeb service專案最近釋出了一個新的主要版本Spring WS 2.0。這個版本要求使用它的工程使用的是Java 5或以上版本及Spring 3.0或以上版本。但是升級到Spring WS 2.0是十分值得的,因為Spring WS 2.0為Java開發者提供了很多好處。

    Spring WS 2.0中的新特性包括:

  • 升級後的更加靈活的@EndPoint程式設計模型
  • 新的整合測試框架,提供對伺服器端和客戶端的測試。
  • Java 5 API(泛型,可變數目引數)等

    Spring WS是Springportfolio其中一個專案,可以用來開發基於Spring的、面向文件的SOAP Web service。和其他的Java SOAP開發工具不過的是,Spring WS只支援約定優先的Web service開發風格。Spring WS關注與XML訊息,並且它不是程式碼生成器(處理從XSD動態生成WSDL之外)。

    在過去的幾周,我正在學習SpringWS 2.0,本文中我將分享我的一點經驗,向大家介紹怎樣使用Spring WS 2.0建立一個簡單的SOAP Web service。

建立一個新的Spring WS 2.0工程

    使用Maven原型,很容易就可以建立一個新的Spring WS工程。如果你的機器上安裝了Maven 2,只需要執行以下的命令:

  1. mvn archetype:create-DarchetypeGroupId=org.springframework.ws-DarchetypeArtifactId=spring-ws-archetype -DarchetypeVersion=2.0.0.RELEASE-DgroupId=com.shekhar.usermanagement -DartifactId=profileService
複製程式碼    這個命令會建立一個基於Maven2的Spring WS工程,帶有所有需要的配置。除了pom.xml之外,原型還會建立spring-ws-servlet.xml和web.xml檔案。Web.xml檔案是標準的Web應用程式佈署描述符,這個檔案中將所有的輸入請求都對映到MessageDispatcherServlet。Spring-ws-servlet.xml檔案包含所有的Spring-WS相關的bean,例如endpoints,WebServiceMessageReceivers,攔截器等等。這個檔案的名字是web.xml檔案中定義的servlet的名字後面加上-servlet.xml。在web.xml檔案中servlet的名字是spring-ws,因此這個XML檔案的名字叫做spring-ws-servlet.xml。

Spring WS 2.0中的新特性

    本節將介紹Spring WS2.0中最值得一提的新特性。

註解驅動的Endpoint模型

    第一個新特性是在spring-ws-servlet.xml檔案中只需要一行配置。這一行配置(下面會顯示)配置了註解驅動的Spring WS endpoint模型。因此在Spring WS 2.0中,不需要在spring-ws-context.xml檔案中定義任何的bean來配置@Endpoing程式設計模型。

    作為例子,讓我們編寫一個簡單的基於SOAP的web service,該webservice會建立使用者資訊。由於Spring WS遵從約定優先的開發風格,我們應該首先編寫XML約定。我們的web service的XML schema定義如下:

  1. <?xmlversion="1.0" encoding="UTF-8"?>
  2. <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
  3.     elementFormDefault="qualified"targetNamespace="http://shekhar.com/usermanagement/schemas"
  4.     xmlns:schemas="http://shekhar.com/usermanagement/schemas">
  5.     <xs:element name="UserProfileCreateRequest">
  6.         <xs:complexType>
  7.             <xs:sequence>
  8.                 <xs:elementname="UserProfile" type="schemas:UserProfile" />
  9.             </xs:sequence>
  10.         </xs:complexType>
  11.     </xs:element>
  12.     <xs:complexTypename="UserProfile">
  13.         <xs:sequence>
  14.             <xs:elementname="firstName" type="xs:string" />
  15.             <xs:elementname="lastName" type="xs:string" />
  16.             <xs:elementname="age" type="xs:integer" />
  17.         </xs:sequence>
  18.     </xs:complexType>
  19.     <xs:elementname="UserProfileCreateResponse">
  20.         <xs:complexType>
  21.             <xs:sequence>
  22.                 <xs:elementname="message" type="xs:string" />
  23.             </xs:sequence>
  24.         </xs:complexType>
  25.     </xs:element>
  26. </xs:schema>
複製程式碼

使用sws:dynamic-wsdl來自動生成WSDL

    Spring WS讓我們可以選擇從XSD動態生成WSDL。在2.0版之前,我們必須在context檔案中定義一個bean來動態生成WSDL。在SpringWS 2.0中,我們可以通過使用<sws:dynamic-wsdl>標籤來動態生成WSDL。

  1. <sws:dynamic-wsdlid="profile" portTypeName="UserManagement"locationUri="/profileService"   targetNamespace="http://shekhar.com/usermanagement/schemas">
  2. <sws:xsdlocation="/WEB-INF/userManagement.xsd"/>
  3. </sws:dynamic-wsdl>
複製程式碼    我們也可以使用這個標籤來發表已經存在的WSDL。如果我們將這個應用程式佈署在如Jetty或Tomcat的伺服器上,就可以在http://localhost:8080/profileService/profile.wsdl處看到該檔案。

升級了的、更加靈活的@Endpoint模型

    現在我們已經生成了約定(也就是WSDL),但是還沒有編寫會在伺服器端被呼叫的程式碼。在Spring WS中,我們要編寫endpoint來處理輸入的XML訊息。一個endpoint就是一個使用了@Endpoint註解的類。在endpoint類中,我們要建立一個或多個方法來處理輸入請求的XML訊息。處理方法可以接受很多型別的引數和返回值,例如JAXB2,dom4j,XPATH,SAX,STAX等等。也可以將這些型別組合使用(例如,可以使用DOM物件的引數,但是返回JAXB2的響應物件)。

    下面就是Spring WS引入的重要的特性之一。處理方法可以使用@PayloadRoot或@SoapAction註解來指定哪種型別的訊息是該方法能夠處理的。可以從SpringSource文件中獲得完整的支援的引數和返回型別的列表

下面是一個endpoint的例子:

  1. importorg.springframework.beans.factory.annotation.Autowired;
  2. import org.springframework.ws.server.endpoint.annotation.Endpoint;
  3. import org.springframework.ws.server.endpoint.annotation.PayloadRoot;
  4. import org.springframework.ws.server.endpoint.annotation.RequestPayload;
  5. import org.springframework.ws.server.endpoint.annotation.ResponsePayload;
  6. import com.shekhar.usermanagement.profile.UserProfileCreateRequest;
  7. import com.shekhar.usermanagement.profile.UserProfileCreateResponse;
  8. @Endpoint
  9. public class UserProfileEndpoint {
  10.     private UserService service;
  11.     @Autowired
  12.     public UserProfileEndpoint(UserServiceservice) {
  13.         this.service = service;
  14.     }
  15.     @PayloadRoot(localPart ="UserProfileCreateRequest", namespace ="http://shekhar.com/usermanagement/schemas")
  16.     @ResponsePayload
  17.     public UserProfileCreateResponsecreate(@RequestPayload UserProfileCreateRequest request) {
  18.         String message =service.createUser(request.getUserProfile());
  19.         UserProfileCreateResponse response= new UserProfileCreateResponse();
  20.         response.setMessage(message);
  21.         return response;
  22.     }
  23. }
複製程式碼    ”UserProfileCreateRequest”的輸入請求對映到create方法。這個方法中我們使用的是JAXB2物件作為引數和返回值。可以使用Maven 2的外掛來從XSD生成JAXB2 物件。

小結

    從上面的簡單的例子可以看出,使用Spring WS 2.0能夠十分容易的建立基於SOAP的web service。升級後的@Endpoint程式設計模型十分靈活,而且只需要很少的配置。開發人員不必要編寫冗長的配置程式碼,只需要在應用程式的context XML檔案中新增幾個XML標籤就行了。