Spring-WS示例

参考 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();
    }
}

你可能感兴趣的:(spring)