javascript
spring创建web项目_使用Spring WS创建合同优先的Web服务
spring創(chuàng)建web項目
1引言
本文介紹了如何使用來實現(xiàn)和測試SOAP Web服務
Spring Web Services項目 。 本示例將JAXB2用于(取消)編組。 為了開發(fā)服務,我將使用合同優(yōu)先的方法,該方法首先定義服務合同,然后基于此合同實施服務。
本文分為以下幾節(jié):
- 2解釋申請
- 3實施服務
- 3.1創(chuàng)建合同
- 3.2生成Java類
- 3.3實現(xiàn)SOAP端點
- 3.4配置應用程序
- 4測試服務
- 5附加信息
- 5.1實施客戶
- 5.2內部運作方式
2解釋申請
示例應用程序處理訂單。 我們有一個前端控制器(messageDispatcher servlet),它將處理訂單請求,調用服務以處理訂單并返回結果。
您可以在github上獲取源代碼。
3實施服務
3.1創(chuàng)建合同
由于我們將使用“合同優(yōu)先”方法,因此創(chuàng)建合同的最簡單方法是首先定義示例xml文檔,然后,我們將使用工具生成合同。 以下是示例xml文檔:
client-request.xml
<clientDataRequest xmlns="http://www.xpadro.spring.samples.com/orders"clientId="A-123"productId="C5FH"quantity="5" />client-response.xml
<clientDataResponse xmlns="http://www.xpadro.spring.samples.com/orders" confirmationId="7890B"orderDate="2013-09-22"amount="15.50" />為了創(chuàng)建模式,我們可以使用Trang,這是一個開放源代碼工具,將允許我們從xml文檔中生成xsd模式。 我已經將該庫包含到項目構建路徑中(可以從Trang 網站獲得此jar),并且創(chuàng)建了一個Ant任務來執(zhí)行轉換:
generate-schema.xml
<project name="Ant-Generate-Schema-With-Trang" default="generate" basedir="."><property name="src.dir" location="src" /><property name="trang.dir" location="lib" /><property name="source.dir" location="${src.dir}/main/webapp/WEB-INF/schemas/samples" /><property name="schema.dir" location="${src.dir}/main/webapp/WEB-INF/schemas/xsd" /><target name="generate" description="generates order schema"><delete dir="${schema.dir}" /><mkdir dir="${schema.dir}" /><java jar="${trang.dir}/trang.jar" fork="true"><arg value="${source.dir}/client-request.xml" /><arg value="${schema.dir}/client-request.xsd" /></java><java jar="${trang.dir}/trang.jar" fork="true"><arg value="${source.dir}/client-response.xml" /><arg value="${schema.dir}/client-response.xsd" /></java></target> </project>一旦執(zhí)行了Ant任務,它將生成架構。 由于模式是自動生成的,因此我們可能需要進行一些修改以使其適應我們的需求。 讓我們來看看:
客戶端請求
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.xpadro.spring.samples.com/orders" xmlns:orders="http://www.xpadro.spring.samples.com/orders"><xs:element name="clientDataRequest"><xs:complexType><xs:attribute name="clientId" use="required" type="xs:NCName"/><xs:attribute name="productId" use="required" type="xs:NCName"/><xs:attribute name="quantity" use="required" type="xs:integer"/></xs:complexType></xs:element> </xs:schema>客戶端響應
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.xpadro.spring.samples.com/orders" xmlns:orders="http://www.xpadro.spring.samples.com/orders"><xs:element name="clientDataResponse"><xs:complexType><xs:attribute name="amount" use="required" type="xs:decimal"/><xs:attribute name="confirmationId" use="required" type="xs:NMTOKEN"/><xs:attribute name="orderDate" use="required" type="xs:NMTOKEN"/></xs:complexType></xs:element> </xs:schema> 我們可以向這些架構添加不同的驗證,但是在本示例中,我將只修改幾種類型,例如clientId,productId和ConfirmationId(xs:string)和orderDate(xs:date)。 XML數據類型到Java類型的映射由JAXB完成。 您可以檢查提供了哪些映射
在這里 。
為了完成該架構,我們將把response元素復制到請求架構中。 我創(chuàng)建了帶有響應和請求的第三個架構:
客戶端服務
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"elementFormDefault="qualified" targetNamespace="http://www.xpadro.spring.samples.com/orders"xmlns:orders="http://www.xpadro.spring.samples.com/orders"><xs:element name="clientDataRequest"><xs:complexType><xs:attribute name="clientId" use="required" type="xs:string" /><xs:attribute name="productId" use="required" type="xs:string" /><xs:attribute name="quantity" use="required" type="xs:integer" /></xs:complexType></xs:element><xs:element name="clientDataResponse"><xs:complexType><xs:attribute name="amount" use="required" type="xs:decimal" /><xs:attribute name="confirmationId" use="required" type="xs:string" /><xs:attribute name="orderDate" use="required" type="xs:date" /></xs:complexType></xs:element> </xs:schema>最后一步是寫合同,通常用WSDL文件表示。 如果您不想手動創(chuàng)建它,Spring-ws項目為我們提供了一種從XSD模式生成此文件的方法。 您將在配置應用程序部分中看到第二種方法。
3.2生成Java類
我們將使用JAXB2生成請求和響應對象。 JAXB的XJC編譯器將負責從我們之前生成的XSD架構轉換這些對象。 它將作為Ant任務執(zhí)行:
<project name="Ant-Generate-Classes-With-JAXB2" default="generate" basedir="."><property name="src.dir" location="src" /><property name="java.dir" location="src/main/java" /><property name="schema.dir" location="${src.dir}/main/webapp/WEB-INF/schemas/xsd" /><target name="generate"><exec executable="xjc"><arg line=" -d ${java.dir} -p xpadro.spring.ws.types ${schema.dir}/client-service.xsd" /></exec></target> </project>該任務將在xpadro.spring.ws.types包中創(chuàng)建Java類(您可能需要刷新項目)。
3.3實現(xiàn)SOAP端點
端點接收未編組的消息有效負載,并使用此數據來調用訂單服務。 然后它將返回服務響應,該響應將由端點適配器編組:
@Endpoint public class OrderEndpoint {@Autowiredprivate OrderService orderService;@PayloadRoot(localPart="clientDataRequest", namespace="http://www.xpadro.spring.samples.com/orders")public @ResponsePayload ClientDataResponse order(@RequestPayload ClientDataRequest orderData) {OrderConfirmation confirmation = orderService.order(orderData.getClientId(), orderData.getProductId(), orderData.getQuantity().intValue());ClientDataResponse response = new ClientDataResponse();response.setConfirmationId(confirmation.getConfirmationId());BigDecimal amount = new BigDecimal(Float.toString(confirmation.getAmount()));response.setAmount(amount);response.setOrderDate(convertDate(confirmation.getOrderDate()));return response;}//date conversion }這是端點使用的注釋的簡短描述:
@Endpoint :將類注冊為組件。 這樣,將通過組件掃描檢測到該類。
@PayloadRoot :將端點方法注冊為請求的處理程序。 該注釋將定義該方法可以處理的請求消息類型。 在我們的示例中,它將接收消息,其中其有效負載根元素具有與我們創(chuàng)建的XSD架構中定義的名稱空間相同的名稱空間,并且其本地名稱是為請求定義的名稱(clientDataRequest)。
@RequestPayload :指示要作為參數傳遞給方法的請求消息的有效負載。
@ResponsePayload ,指示將返回值用作響應消息的有效負載。
3.4配置應用程序
web.xml
應用程序配置(如數據源,transactionManager等)
加載應用程序上下文
<listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>這是一個Servlet,它將充當處理所有SOAP調用的前端控制器。 它的功能是將傳入的XML消息派生到端點,就像Spring MVC的DispatcherServlet一樣。
<servlet><servlet-name>orders</servlet-name><servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:xpadro/spring/ws/config/servlet-config.xml</param-value></init-param><load-on-startup>1</load-on-startup> </servlet><servlet-mapping><servlet-name>orders</servlet-name><url-pattern>/orders/*</url-pattern> </servlet-mapping> servlet-config.xml
此配置包含Web服務基礎結構bean。
在動態(tài)wsdl中,在locationUri屬性中輸入什么值都沒有關系,因為它將由MessageDispatcherServlet處理。 因此,wsdl將在以下位置可用:
http:// localhost:8081 / spring-ws / orders / whatever / orderDefinition.wsdl
4測試服務
下面的示例創(chuàng)建一個模擬客戶端,該客戶端將訪問Web服務:
@ContextConfiguration("classpath:xpadro/spring/ws/test/config/test-server-config.xml") @RunWith(SpringJUnit4ClassRunner.class) public class TestWebService {@AutowiredApplicationContext context;private MockWebServiceClient mockClient;@Testpublic void testValidOrderRequest() {Source requestPayload = new StringSource("<clientDataRequest xmlns='http://www.xpadro.spring.samples.com/orders' " +"clientId='123' productId='XA-55' quantity='5'/>");Source responsePayload = new StringSource("<clientDataResponse xmlns='http://www.xpadro.spring.samples.com/orders' " +"amount='55.99' confirmationId='GHKG34L' orderDate='2013-10-26+02:00'/>");RequestCreator creator = RequestCreators.withPayload(requestPayload);mockClient = MockWebServiceClient.createClient(context);mockClient.sendRequest(creator).andExpect(ResponseMatchers.payload(responsePayload));}@Testpublic void testInvalidOrderRequest() {Source requestPayload = new StringSource("<clientDataRequest xmlns='http://www.xpadro.spring.samples.com/orders' " +"clientId='456' productId='XA-55' quantity='5'/>");Source responsePayload = new StringSource("<SOAP-ENV:Fault xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>" +"<faultcode>SOAP-ENV:Server</faultcode><faultstring xml:lang='en'>Client [456] not found</faultstring></SOAP-ENV:Fault>");RequestCreator creator = RequestCreators.withPayload(requestPayload);mockClient = MockWebServiceClient.createClient(context);mockClient.sendRequest(creator).andExpect(ResponseMatchers.payload(responsePayload));} }此測試中使用的配置文件非常簡單,僅包含對服務組件的掃描:
<context:component-scan base-package="xpadro.spring.ws"/> <ws:annotation-driven/>5附加信息
5.1實施客戶
為了方便客戶端訪問Web服務,Spring為我們提供了WebServiceTemplate類。 此類包含用于發(fā)送和接收消息的方法,并且還使用轉換器對(取消)編組對象。
我創(chuàng)建了一個充當服務客戶端的測試:
@ContextConfiguration("classpath:xpadro/spring/ws/test/config/client-config.xml") @RunWith(SpringJUnit4ClassRunner.class) public class TestClient {@Autowired WebServiceTemplate wsTemplate;@Testpublic void invokeOrderService() throws Exception {ClientDataRequest request = new ClientDataRequest();request.setClientId("123");request.setProductId("XA-55");request.setQuantity(new BigInteger("5", 10));ClientDataResponse response = (ClientDataResponse) wsTemplate.marshalSendAndReceive(request);assertNotNull(response);assertEquals(new BigDecimal("55.99"), response.getAmount());assertEquals("GHKG34L", response.getConfirmationId());} }配置測試文件包含WebServiceTemplate配置:
<oxm:jaxb2-marshaller id="marshaller" contextPath="xpadro.spring.ws.types"/><bean class="org.springframework.ws.client.core.WebServiceTemplate"><property name="marshaller" ref="marshaller" /><property name="unmarshaller" ref="marshaller" /><property name="defaultUri" value="http://localhost:8081/spring-ws/orders" /> </bean>只需記住在執(zhí)行此測試之前使用已部署的Web服務應用程序啟動服務器即可。
5.2內部運作方式
如果您只想實現(xiàn)Web服務,那么上一節(jié)將結束本文。 對于那些對它如何真正起作用感到好奇的人,我將嘗試解釋如何將請求映射到端點,這比到目前為止的解釋要低一些。
當請求到達MessageDispatcher時,它依賴于兩個組件:
端點映射
MessageDispatcher包含一個端點映射列表,每個端點映射都包含一個先前注冊的方法端點的映射。 在我們的例子中,JAXB映射PayloadRootAnnotationMethodEndpointMapping已注冊所有帶有@PayloadRoot注釋的方法。 如果消息的有效負載的合格名稱解析為注冊方法,則它將被返回給MessageDispatcher。 如果我們不注釋我們的方法,它將無法處理請求。
端點適配器
然后,MessageDispatcher將詢問其每個端點適配器是否支持當前請求。 在我們的情況下,適配器檢查以下兩個條件是否都成立:
- 傳遞給該方法的至少一個參數使用@RequestPayload進行注釋
- 如果端點方法返回響應,則必須使用@ResponsePayload進行注釋
如果返回了適配器,則它將調用端點,在將參數傳遞給方法之前將其解組。 當該方法返回響應時,適配器將封送它。
下圖是此步驟的簡化版本,以簡化操作:
結論
我們已經看到了有關如何實現(xiàn)簡單的Web服務然后對其進行測試的介紹。 如果您有興趣,還可以看看如何使用MockWebServiceServer 測試客戶端。
參考: XavierPadró博客博客中的JCG合作伙伴 Xavier Padro 使用Spring WS創(chuàng)建了合同優(yōu)先的Web服務 。翻譯自: https://www.javacodegeeks.com/2014/02/creating-contract-first-web-services-with-spring-ws.html
spring創(chuàng)建web項目
總結
以上是生活随笔為你收集整理的spring创建web项目_使用Spring WS创建合同优先的Web服务的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring Data Redis:Se
- 下一篇: gradle idea java ssm