一個簡單的Spring Web Service示例
剛接觸web service,好不容易找到一篇spring-ws的例子,還琢磨了好長一段時間,很多概念性的問題都沒弄清楚。只能依葫蘆畫瓢,照搬過來,稍微修改了一下,使結構更加清晰,原文出自http://fuxueliang.javaeye.com/blog/175184#。
基本環境:
JDK6、Tomcat 6.0、MyEclipse 6.6、spring 2.0、spring-ws-1.5.5
1、spring-ws-servlet.xml
這個地方出現了一段插曲,hello.wsdl放在WEB-INF下老是報錯,說hello.wsdl找不到,後來放到classpath下才OK。
建立一個Web專案, 由於Spring Web Service是基於Spring MVC的, 在web.xml中新增如下servlet, 並在WEB-INF下建立SpringMVC的預設配置檔案spring-ws-servlet.xml:
- <?xmlversion="1.0"encoding="UTF-8"?>
- <beansxmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
- <beanid="payloadMapping"class="org.springframework.ws.server.endpoint.mapping.PayloadRootQNameEndpointMapping">
- <propertyname="endpointMap">
- <map>
- <entrykey="{http://www.ispring.com/ws/hello}eRequest">
- <refbean="helloEndpoint"/>
- </entry>
- </map>
- </property>
- </bean>
- <beanid="hello"class="org.springframework.ws.wsdl.wsdl11.SimpleWsdl11Definition">
- <!-- --><propertyname="wsdl"value="classpath://hello.wsdl"></property>
- <!-- <property name="wsdl" value="/WEB_INF/hello.wsdl"></property> -->
- <!-- <constructor-arg value="/WEB_INF/hello.wsdl"/> -->
- </bean>
- <beanid="helloEndpoint"class="com.sws.HelloEndPoint">
- <propertyname="helloService"ref="helloService"></property>
- </bean>
- <beanid="helloService"class="com.sws.HelloServiceImpl"></bean>
- </beans>
其中最主要的bean就是payloadMapping, 它定義了接收到的message與endpoint之間的mapping關係:將SOAP Body中包含的xml的根節點的QName為{http://www.fuxueliang.com/ws/hello}HelloRequest交給helloEndpoint處理.
SimpleWsdl11Definition這個bean則是定義了這個服務的wsdl, 訪問地址是:
2、web.xml
- <?xmlversion="1.0"encoding="UTF-8"?>
- <web-appversion="2.4"
- xmlns="http://java.sun.com/xml/ns/j2ee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
- http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
- <!-- begin Spring配置
- <context-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>
- /WEB-INF/spring-ws-servlet.xml,
- </param-value>
- </context-param>
- <listener>
- <listener-class>
- org.springframework.web.context.ContextLoaderListener
- </listener-class>
- </listener>
- <listener>
- <listener-class>
- org.springframework.web.util.IntrospectorCleanupListener
- </listener-class>
- </listener>-->
- <!-- end Spring配置 -->
- <servlet>
- <servlet-name>spring-ws</servlet-name>
- <servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
- </servlet>
- <servlet-mapping>
- <servlet-name>spring-ws</servlet-name>
- <url-pattern>/*</url-pattern>
- </servlet-mapping>
- <welcome-file-list>
- <welcome-file>index.jsp</welcome-file>
- </welcome-file-list>
- </web-app>
3、hello.wsdl
- <?xmlversion="1.0"encoding="UTF-8"?>
- <wsdl:definitions
- xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
- xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
- xmlns:schema="http://www.ispring.com/ws/hello"
- xmlns:tns="http://www.ispring.com/ws/hello/definitions"
- targetNamespace="http://www.ispring.com/ws/hello/definitions">
- <wsdl:types>
- <schemaxmlns="http://www.w3.org/2001/XMLSchema"
- targetNamespace="http://www.ispring.com/ws/hello">
- <elementname="dRequest"type="string"/>
- <elementname="dResponse"type="string"/>
- </schema>
- </wsdl:types>
- <wsdl:messagename="bRequest">
- <wsdl:partelement="schema:dRequest"name="cRequest"/>
- </wsdl:message>
- <wsdl:messagename="bResponse">
- <wsdl:partelement="schema:dResponse"name="cResponse"/>
- </wsdl:message>
- <wsdl:portTypename="HelloPortType">
- <wsdl:operationname="sayHello">
- <wsdl:inputmessage="tns:bRequest"name="aRequest"/>
- <wsdl:outputmessage="tns:bResponse"name="aResponse"/>
- </wsdl:operation>
- </wsdl:portType>
- <wsdl:bindingname="HelloBinding"type="tns:HelloPortType">
- <soap:bindingstyle="document"transport="http://schemas.xmlsoap.org/soap/http"/>
- <wsdl:operationname="sayHello">
- <soap:operationsoapAction=""/>
- <wsdl:inputname="aRequest">
- <soap:bodyuse="literal"/>
- </wsdl:input>
- <wsdl:outputname="aResponse">
- <soap:bodyuse="literal"/>
- </wsdl:output>
- </wsdl:operation>
- </wsdl:binding>
- <wsdl:servicename="HelloService">
- <wsdl:portbinding="tns:HelloBinding"name="HelloPort">
- <soap:addresslocation="http://localhost:8088/springws/webservice"/>
- </wsdl:port>
- </wsdl:service>
- </wsdl:definitions>
4、HelloService.java
- package com.sws;
- publicinterface HelloService {
- String sayHello(String name);
- }
5、HelloServiceImpl.java
- package com.sws;
- publicclass HelloServiceImpl implements HelloService {
- @Override
- public String sayHello(String name) {
- return"Hello, " + name + "!";
- }
- }
6、HelloEndPoint.java
實現一個EndPoint來處理接收到的xml及返回xml.當然, Spring Web Service提供了很多抽象的實現, 包括Dom4j, JDom等等.這裡我們使用JDK自帶的, 需要繼承org.springframework.ws.server.endpoint.AbstractDomPayloadEndpoint.
- package com.sws;
- import org.springframework.util.Assert;
- import org.springframework.ws.server.endpoint.AbstractDomPayloadEndpoint;
- import org.w3c.dom.Document;
- import org.w3c.dom.Element;
- import org.w3c.dom.Node;
- import org.w3c.dom.NodeList;
- import org.w3c.dom.Text;
- publicclass HelloEndPoint extends AbstractDomPayloadEndpoint{
- /**
- * Namespace of both request and response
- */
- publicstaticfinal String NAMESPACE_URI = "http://www.ispring.com/ws/hello";
- /**
- * The local name of the expected request
- */
- publicstaticfinal String HELLO_REQUEST_LOCAL_NAME = "eRequest";
- /**
- * The local name of the created response
- */
- publicstaticfinal String HELLO_RESPONSE_LOCAL_NAME = "fResponse";
- private HelloService helloService;
- @Override
- protected Element invokeInternal(Element requestElement, Document document)throws Exception {
- Assert.isTrue(NAMESPACE_URI.equals(requestElement.getNamespaceURI()), "Invalid namespace");
- Assert.isTrue(HELLO_REQUEST_LOCAL_NAME.equals(requestElement.getLocalName()), "Invalid local name");
- NodeList children = requestElement.getChildNodes();
- Text requestText = null;
- for(int i=0; i<children.getLength(); i++){
- if(children.item(i).getNodeType() == Node.TEXT_NODE){
- requestText = (Text) children.item(i);
- }
- }
- if(requestText == null){
- thrownew IllegalArgumentException("Could not find request text node");
- }
- String response = helloService.sayHello(requestText.getNodeValue());
- Element responseElement = document.createElementNS(NAMESPACE_URI, HELLO_RESPONSE_LOCAL_NAME);
- Text responseText = document.createTextNode(response);
- responseElement.appendChild(responseText);
- return responseElement;
- }
- public HelloService getHelloService() {
- return helloService;
- }
- publicvoid setHelloService(HelloService helloService) {
- this.helloService = helloService;
- }
- }
7、HelloWebServiceClient.java(saaj實現)
- package com.sws;
- import java.net.MalformedURLException;
- import java.net.URL;
- import java.util.Iterator;
- import javax.xml.soap.MessageFactory;
- import javax.xml.soap.Name;
- import javax.xml.soap.SOAPBodyElement;
- import javax.xml.soap.SOAPConnection;
- import javax.xml.soap.SOAPConnectionFactory;
- import javax.xml.soap.SOAPEnvelope;
- import javax.xml.soap.SOAPException;
- import javax.xml.soap.SOAPFault;
- import javax.xml.soap.SOAPMessage;
- publicclass HelloWebServiceClient {
- publicstaticfinal String NAMESPACE_URI = "http://www.ispring.com/ws/hello";
- publicstaticfinal String PREFIX = "tns";
- private SOAPConnectionFactory connectionFactory;
- private MessageFactory messageFactory;
- private URL url;
- public HelloWebServiceClient(String url) throws UnsupportedOperationException, SOAPException, MalformedURLException{
- connectionFactory = SOAPConnectionFactory.newInstance();
- messageFactory = MessageFactory.newInstance();
- this.url = new URL(url);
- }
- private SOAPMessage createHelloRequest() throws SOAPException{
- SOAPMessage message = messageFactory.createMessage();
- SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
- Name helloRequestName = envelope.createName("eRequest",PREFIX,NAMESPACE_URI);
- SOAPBodyElement helloRequestElement = message.getSOAPBody().addBodyElement(helloRequestName);
- helloRequestElement.setValue("ispring");
- return message;
- }
- publicvoid callWebService() throws SOAPException{
- SOAPMessage request = createHelloRequest();
- SOAPConnection connection = connectionFactory.createConnection();
- SOAPMessage response = connection.call(request, url);
- if(!response.getSOAPBody().hasFault()){
- writeHelloResponse(response);
- }else{
- SOAPFault fault = response.getSOAPBody().getFault();
- System.err.println("Received SOAP Fault");
- System.err.println("SOAP Fault Code : " + fault.getFaultCode());
- System.err.println("SOAP Fault String : " + fault.getFaultString());
- }
- }
- privatevoid writeHelloResponse(SOAPMessage message) throws SOAPException{
- SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
- Name helloResponseName = envelope.createName("fResponse",PREFIX,NAMESPACE_URI);
- Iterator childElements = message.getSOAPBody().getChildElements(helloResponseName);
- SOAPBodyElement helloResponseElement = (SOAPBodyElement)childElements.next();
- String value = helloResponseElement.getTextContent();
- System.out.println("Hello Response [" + value + "]");
- }
- publicstaticvoid main(String[] args) throws UnsupportedOperationException, MalformedURLException, SOAPException {
- String url = "http://localhost:8088/SpringWS";
- HelloWebServiceClient helloClient = new HelloWebServiceClient(url);
- helloClient.callWebService();
- }
- }