使用Spring WS 2.0開發基於SOAP的web service
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,只需要執行以下的命令:
- mvn archetype:create-DarchetypeGroupId=org.springframework.ws-DarchetypeArtifactId=spring-ws-archetype -DarchetypeVersion=2.0.0.RELEASE-DgroupId=com.shekhar.usermanagement -DartifactId=profileService
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定義如下:
- <?xmlversion="1.0" encoding="UTF-8"?>
- <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
- elementFormDefault="qualified"targetNamespace="http://shekhar.com/usermanagement/schemas"
- xmlns:schemas="http://shekhar.com/usermanagement/schemas">
- <xs:element name="UserProfileCreateRequest">
- <xs:complexType>
- <xs:sequence>
- <xs:elementname="UserProfile" type="schemas:UserProfile" />
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:complexTypename="UserProfile">
- <xs:sequence>
- <xs:elementname="firstName" type="xs:string" />
- <xs:elementname="lastName" type="xs:string" />
- <xs:elementname="age" type="xs:integer" />
- </xs:sequence>
- </xs:complexType>
- <xs:elementname="UserProfileCreateResponse">
- <xs:complexType>
- <xs:sequence>
- <xs:elementname="message" type="xs:string" />
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- </xs:schema>
使用sws:dynamic-wsdl來自動生成WSDL
Spring WS讓我們可以選擇從XSD動態生成WSDL。在2.0版之前,我們必須在context檔案中定義一個bean來動態生成WSDL。在SpringWS 2.0中,我們可以通過使用<sws:dynamic-wsdl>標籤來動態生成WSDL。
- <sws:dynamic-wsdlid="profile" portTypeName="UserManagement"locationUri="/profileService" targetNamespace="http://shekhar.com/usermanagement/schemas">
- <sws:xsdlocation="/WEB-INF/userManagement.xsd"/>
- </sws:dynamic-wsdl>
升級了的、更加靈活的@Endpoint模型
現在我們已經生成了約定(也就是WSDL),但是還沒有編寫會在伺服器端被呼叫的程式碼。在Spring WS中,我們要編寫endpoint來處理輸入的XML訊息。一個endpoint就是一個使用了@Endpoint註解的類。在endpoint類中,我們要建立一個或多個方法來處理輸入請求的XML訊息。處理方法可以接受很多型別的引數和返回值,例如JAXB2,dom4j,XPATH,SAX,STAX等等。也可以將這些型別組合使用(例如,可以使用DOM物件的引數,但是返回JAXB2的響應物件)。
下面就是Spring WS引入的重要的特性之一。處理方法可以使用@PayloadRoot或@SoapAction註解來指定哪種型別的訊息是該方法能夠處理的。可以從SpringSource文件中獲得完整的支援的引數和返回型別的列表。
下面是一個endpoint的例子:
- importorg.springframework.beans.factory.annotation.Autowired;
- import org.springframework.ws.server.endpoint.annotation.Endpoint;
- import org.springframework.ws.server.endpoint.annotation.PayloadRoot;
- import org.springframework.ws.server.endpoint.annotation.RequestPayload;
- import org.springframework.ws.server.endpoint.annotation.ResponsePayload;
- import com.shekhar.usermanagement.profile.UserProfileCreateRequest;
- import com.shekhar.usermanagement.profile.UserProfileCreateResponse;
- @Endpoint
- public class UserProfileEndpoint {
- private UserService service;
- @Autowired
- public UserProfileEndpoint(UserServiceservice) {
- this.service = service;
- }
- @PayloadRoot(localPart ="UserProfileCreateRequest", namespace ="http://shekhar.com/usermanagement/schemas")
- @ResponsePayload
- public UserProfileCreateResponsecreate(@RequestPayload UserProfileCreateRequest request) {
- String message =service.createUser(request.getUserProfile());
- UserProfileCreateResponse response= new UserProfileCreateResponse();
- response.setMessage(message);
- return response;
- }
- }
小結
從上面的簡單的例子可以看出,使用Spring WS 2.0能夠十分容易的建立基於SOAP的web service。升級後的@Endpoint程式設計模型十分靈活,而且只需要很少的配置。開發人員不必要編寫冗長的配置程式碼,只需要在應用程式的context XML檔案中新增幾個XML標籤就行了。