参考
http://blog.csdn.net/thinkghoster/article/details/3414304
Creating a Web service with Spring-WS
http://docs.spring.io/spring-ws/site/reference/html/server.html
难点:
1. wsdl文件说明;
WSDL 详解
http://panyongzheng.iteye.com/blog/1669447
2. 发布点EndPoint的实现;
3. 客户端如何发送和检索响应信息;
技巧: 使用SAAJ发送和接收SOAP消息
http://www.ibm.com/developerworks/cn/xml/x-jaxmsoap/
提供和响应双方共识的契约
hello.wsdl
<?xml version="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>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.ispring.com/ws/hello">
<element name="typeRequest" type="string" />
<element name="typeResponse" type="string" />
</schema>
</wsdl:types>
<wsdl:message name="messageRequest">
<wsdl:part element="schema:typeRequest" name="messageRequestName" />
</wsdl:message>
<wsdl:message name="messageResponse">
<wsdl:part element="schema:typeResponse" name="messageResponseName" />
</wsdl:message>
<wsdl:portType name="HelloPortType">
<wsdl:operation name="sayHello">
<wsdl:input message="tns:messageRequest" name="portTypeRequest" />
<wsdl:output message="tns:messageResponse" name="portTypeResponse" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="HelloBinding" type="tns:HelloPortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="sayHello">
<soap:operation soapAction="" />
<wsdl:input name="portTypeRequest">
<soap:body use="literal" />
</wsdl:input>
<wsdl:output name="portTypeResponse">
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="HelloService">
<wsdl:port binding="tns:HelloBinding" name="HelloPort">
<!-- 这里是ws客户端访问地址 -->
<soap:address location="http://localhost:8080/SpringWS/ws/hello" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
源码
=======================================================================
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>SpringWS</groupId>
<artifactId>SpringWS</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>3.2.8.RELEASE</spring.version>
<spring.ws.version>2.1.4.RELEASE</spring.ws.version>
</properties>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-ws-core</artifactId>
<version>${spring.ws.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<url>http://localhost:8080/manager/text</url>
<username>admin</username>
<password>admin</password>
<path>/SpringWS</path>
</configuration>
</plugin>
</plugins>
</build>
</project>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0">
<display-name>Spring3MVC</display-name>
<!-- 配置SpringMVC的applicationContext.xml文件位置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- 配置SpringMVC -->
<servlet>
<servlet-name>spring-mvc-servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring-mvc-servlet</servlet-name>
<url-pattern>/web/*</url-pattern>
</servlet-mapping>
<!-- 配置SpringWS -->
<servlet>
<servlet-name>spring-ws-servlet</servlet-name>
<servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-ws-servlet.xml</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring-ws-servlet</servlet-name>
<url-pattern>*.wsdl</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>spring-ws-servlet</servlet-name>
<url-pattern>/ws/*</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"
default-autowire="byName" default-lazy-init="true">
<context:component-scan base-package="com">
<context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation" />
</context:component-scan>
</beans>
spring-mvc-servlet.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
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-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<context:component-scan base-package="com">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository" />
</context:component-scan>
<mvc:annotation-driven/>
<mvc:resources location="/resources/" mapping="/resources/**"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
spring-ws-servlet.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
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-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<!--
定义了接收到的message与endpoint之间的mapping关系:将SOAP Body中包含的xml的根节点的QName为{http://www.fuxueliang.com/ws/hello}HelloRequest交给helloEndpoint处理.
-->
<bean id="payloadMapping" class="org.springframework.ws.server.endpoint.mapping.PayloadRootQNameEndpointMapping">
<property name="endpointMap">
<map>
<entry key="{http://www.ispring.com/ws/hello}serviceRequest">
<ref bean="helloEndpoint"/>
</entry>
</map>
</property>
</bean>
<!--
SimpleWsdl11Definition这个bean则是定义了这个服务的wsdl, 访问地址是:
http://localhost:8080/springws/hello.wsdl.
-->
<bean id="hello" class="org.springframework.ws.wsdl.wsdl11.SimpleWsdl11Definition">
<property name="wsdl" value="classpath:/hello.wsdl"></property>
</bean>
<bean id="helloEndpoint" class="com.endPoint.HelloEndPoint">
<property name="helloService" ref="helloService"></property>
</bean>
<bean id="helloService" class="com.service.impl.HelloServiceImpl"></bean>
</beans>
接口于实现
HelloService.java
package com.service;
/**
* Created by Administrator on 14-5-19.
*/
public interface HelloService {
public String sayHello(String name);
}
HelloServiceImpl.java
package com.service.impl;
import com.service.HelloService;
/**
* Created by Administrator on 14-5-19.
*/
public class HelloServiceImpl implements HelloService {
@Override
public String sayHello(String name) {
return "返回到客户端信息: Hello, " + name + "!";
}
}
HelloEndPoint.java
实现一个EndPoint来处理接收到的xml及返回xml.当然, Spring Web Service提供了很多抽象的实现, 包括Dom4j, JDom等等.这里我们使用JDK自带的, 需要继承org.springframework.ws.server.endpoint.AbstractDomPayloadEndpoint.
package com.endPoint;
import com.service.HelloService;
import org.springframework.util.Assert;
import org.springframework.ws.server.endpoint.AbstractDomPayloadEndpoint;
import org.w3c.dom.*;
/**
* Created by Administrator on 14-5-19.
* 实现一个EndPoint来处理接收到的xml及返回xml.当然, Spring Web Service提供了很多抽象的实现,
* 包括Dom4j, JDom等等.这里我们使用JDK自带的,
* 需要继承org.springframework.ws.server.endpoint.AbstractDomPayloadEndpoint.
*/
public class HelloEndPoint extends AbstractDomPayloadEndpoint {
//请求和响应的命名空间
public static final String NAMESPACE_URI = "http://www.ispring.com/ws/hello";
//预期要求的本地名称
public static final String HELLO_REQUEST_LOCAL_NAME = "serviceRequest";
// 创建响应的本地名称
public static final String HELLO_RESPONSE_LOCAL_NAME = "serviceResponse";
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){
throw new 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;
}
public void setHelloService(HelloService helloService) {
this.helloService = helloService;
}
}
7、HelloWebServiceClient.java(saaj实现)
package com.client;
/**
* Created by Administrator on 14-5-19.
*/
import javax.xml.soap.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Iterator;
public class HelloWebServiceClient {
public static final String NAMESPACE_URI = "http://www.ispring.com/ws/hello";
public static final 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);
}
/**
*创建要远程调用的负载
* @throws SOAPException
*/
private SOAPMessage createHelloRequest() throws SOAPException{
SOAPMessage message = messageFactory.createMessage();
SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
Name helloRequestName = envelope.createName("serviceRequest",PREFIX,NAMESPACE_URI);
SOAPBodyElement helloRequestElement = message.getSOAPBody().addBodyElement(helloRequestName);
helloRequestElement.setValue("提交到服务器信息");
return message;
}
public void 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());
}
}
private void writeHelloResponse(SOAPMessage message) throws SOAPException{
SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
Name helloResponseName = envelope.createName("serviceResponse",PREFIX,NAMESPACE_URI);
Iterator childElements = message.getSOAPBody().getChildElements(helloResponseName);
SOAPBodyElement helloResponseElement = (SOAPBodyElement)childElements.next();
String value = helloResponseElement.getTextContent();
System.out.println("调用Spring-WS返回信息: [" + value + "]");
}
public static void main(String[] args) throws UnsupportedOperationException, MalformedURLException, SOAPException {
//在wsdl已经规定好了访问地址
String url = "http://localhost:8080/SpringWS/ws/hello";
HelloWebServiceClient helloClient = new HelloWebServiceClient(url);
helloClient.callWebService();
}
}