SpringWS(二)-入門

    官方幫助手冊:http://docs.spring.io/spring-ws/site/reference/html/tutorial.htmlhtml

    接着《SpringWS(一)-環境搭建》所搭建的服務,運行項目訪問地址:http://localhost:8080/Spring-WS-Demo-01/service/UserService.wsdl;SpringWS會根據咱們定義的Schema來生成wsdl。那這篇文章就繼續開展咱們的後臺處理邏輯,究竟SpringWS對於Web Service請求是如何處理的?過於細節的東西就不詳細說了,後續的博客都會提到,如今先把大概的脈絡搭建起來。java

1、根據SpringWS生成的WSDL,服務端根據接口來定義AddRequest.java,AddResponse.java等文件,可是這些工做是能夠交給MyEclipse去生成的,能夠經過NEW->「Web Service Client」,不清楚的能夠百度。雖然MyEclipse會自動幫咱們生成不少文件,可是用到的就那幾個,分別是AddRequest,AddResponse,GetUserByUserNameRequest,GetUserByUserNameResponse,User 以下:web

package ws.user.model; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; import ws.user.endpoint.UserServiceEndpoint; /** * <p> * Java class for anonymous complex type. * * <p> * The following schema fragment specifies the expected content contained within * this class. * * <pre> * &lt;complexType> * &lt;complexContent> * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> * &lt;all> * &lt;element ref="{http://localhost/ws/UserService}User"/> * &lt;/all> * &lt;/restriction> * &lt;/complexContent> * &lt;/complexType> * </pre> * * */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = { }) @XmlRootElement(name = "AddRequest", namespace=UserServiceEndpoint.USER_SERVICE_NAMESPACE) public class AddRequest { @XmlElement(name = "User", namespace = "http://localhost/ws/UserService", required = true) protected User user; /** * Gets the value of the user property. * * @return possible object is {@link User } * */
    public User getUser() { return user; } /** * Sets the value of the user property. * * @param value * allowed object is {@link User } * */
    public void setUser(User value) { this.user = value; } }
View Code
package ws.user.model; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; import ws.user.endpoint.UserServiceEndpoint; /** * <p> * Java class for anonymous complex type. * * <p> * The following schema fragment specifies the expected content contained within * this class. * * <pre> * &lt;complexType> * &lt;complexContent> * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> * &lt;all> * &lt;element name="success" type="{http://www.w3.org/2001/XMLSchema}boolean"/> * &lt;/all> * &lt;/restriction> * &lt;/complexContent> * &lt;/complexType> * </pre> * * */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = { }) @XmlRootElement(name = "AddResponse", namespace=UserServiceEndpoint.USER_SERVICE_NAMESPACE) public class AddResponse { protected boolean success; /** * Gets the value of the success property. * */
    public boolean isSuccess() { return success; } /** * Sets the value of the success property. * */
    public void setSuccess(boolean value) { this.success = value; } }
View Code
package ws.user.model; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; import ws.user.endpoint.UserServiceEndpoint; /** * <p> * Java class for anonymous complex type. * * <p> * The following schema fragment specifies the expected content contained within * this class. * * <pre> * &lt;complexType> * &lt;complexContent> * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> * &lt;all> * &lt;element name="username"> * &lt;simpleType> * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string"> * &lt;maxLength value="20"/> * &lt;/restriction> * &lt;/simpleType> * &lt;/element> * &lt;/all> * &lt;/restriction> * &lt;/complexContent> * &lt;/complexType> * </pre> * * */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = { }) @XmlRootElement(name = "GetUserByUserNameRequest", namespace=UserServiceEndpoint.USER_SERVICE_NAMESPACE) public class GetUserByUserNameRequest { @XmlElement(required = true) protected String username; /** * Gets the value of the username property. * * @return possible object is {@link String } * */
    public String getUsername() { return username; } /** * Sets the value of the username property. * * @param value * allowed object is {@link String } * */
    public void setUsername(String value) { this.username = value; } }
View Code
package ws.user.model; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; import ws.user.endpoint.UserServiceEndpoint; /** * <p> * Java class for anonymous complex type. * * <p> * The following schema fragment specifies the expected content contained within * this class. * * <pre> * &lt;complexType> * &lt;complexContent> * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> * &lt;all> * &lt;element ref="{http://localhost/ws/UserService}User"/> * &lt;/all> * &lt;/restriction> * &lt;/complexContent> * &lt;/complexType> * </pre> * * */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = { }) @XmlRootElement(name = "GetUserByUserNameResponse", namespace=UserServiceEndpoint.USER_SERVICE_NAMESPACE) public class GetUserByUserNameResponse { @XmlElement(name = "User", namespace = "http://localhost/ws/UserService", required = true) protected User user; /** * Gets the value of the user property. * * @return possible object is {@link User } * */
    public User getUser() { return user; } /** * Sets the value of the user property. * * @param value * allowed object is {@link User } * */
    public void setUser(User value) { this.user = value; } }
View Code
package ws.user.model; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; import ws.user.endpoint.UserServiceEndpoint; /** * <p> * Java class for anonymous complex type. * * <p> * The following schema fragment specifies the expected content contained within * this class. * * <pre> * &lt;complexType> * &lt;complexContent> * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> * &lt;all> * &lt;element name="username"> * &lt;simpleType> * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string"> * &lt;pattern value="[a-zA-Z0-9]{1,20}"/> * &lt;/restriction> * &lt;/simpleType> * &lt;/element> * &lt;element name="password"> * &lt;simpleType> * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string"> * &lt;minLength value="6"/> * &lt;maxLength value="15"/> * &lt;/restriction> * &lt;/simpleType> * &lt;/element> * &lt;/all> * &lt;/restriction> * &lt;/complexContent> * &lt;/complexType> * </pre> * * */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = { }) @XmlRootElement(name = "User", namespace=UserServiceEndpoint.USER_SERVICE_NAMESPACE) public class User { @XmlElement(required = true) protected String username; @XmlElement(required = true) protected String password; /** * Gets the value of the username property. * * @return possible object is {@link String } * */
    public String getUsername() { return username; } /** * Sets the value of the username property. * * @param value * allowed object is {@link String } * */
    public void setUsername(String value) { this.username = value; } /** * Gets the value of the password property. * * @return possible object is {@link String } * */
    public String getPassword() { return password; } /** * Sets the value of the password property. * * @param value * allowed object is {@link String } * */
    public void setPassword(String value) { this.password = value; } }
View Code

 PS:自動生成的幾個類,可能還有點美中不足的地方,就是在每一個類@XmlRootElement中沒有指定命名空間,因此當咱們用MyEclipse生成的時候,最後記得把命名空間補上,這裏能夠方便SpringWS幫咱們完成XML的序列化工做,咱們只管寫業務邏輯就足夠了(上面的類中我已經補充完整了)。spring

2、我如今發佈了服務,客戶端能夠向服務端發送請求,那服務端怎麼接收請求並回應呢?新建一個類,代碼以下(這裏列舉了幾個endpoind的處理方式,能夠選擇本身須要的處理方式):dom

package ws.user.endpoint; import org.dom4j.Element; import org.springframework.beans.factory.annotation.Value; import org.springframework.ws.context.MessageContext; 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 ws.user.model.AddRequest; import ws.user.model.AddResponse; import ws.user.service.IUserServcie; @Endpoint public class UserServiceEndpoint { //UserService.xsd聲明的命名空間
    public static final String USER_SERVICE_NAMESPACE = "http://localhost/ws/UserService"; //注入業務邏輯處理對象
    @Value("#{userServcie}") private IUserServcie userServcie; @PayloadRoot(namespace = USER_SERVICE_NAMESPACE, localPart = "AddRequest") public @ResponsePayload AddResponse handleAddRequest(@RequestPayload AddRequest addRequest) throws Exception { //業務邏輯處理
        boolean success = userServcie.add(addRequest.getUser()); AddResponse response = new AddResponse(); response.setSuccess(success); return response; } /*@PayloadRoot(namespace = USER_SERVICE_NAMESPACE, localPart = "AddRequest") public @ResponsePayload AddResponse handleAddRequest(@RequestPayload DOMSource domSource, SoapHeader header) throws TransformerException { StringResult rs = new StringResult(); TransformerFactory tf = TransformerFactory.newInstance(); Transformer transformer = tf.newTransformer(); transformer.transform(domSource, rs); System.out.println(rs); System.out.println(header.getAllAttributes().hasNext()); while(header.getAllAttributes().hasNext()) { System.out.println(header.getAllAttributes().next()); } AddResponse response = new AddResponse(); response.setSuccess(false); return response; }*/
    
    /*@PayloadRoot(namespace = USER_SERVICE_NAMESPACE, localPart = "AddRequest") public @ResponsePayload AddResponse handle(@RequestPayload Element element) { //element:原始的XML報文 System.out.println(element.asXML()); AddResponse response = new AddResponse(); response.setSuccess(false); return response; }*/
    
    /* @PayloadRoot(namespace = USER_SERVICE_NAMESPACE, localPart = "AddRequest") public @ResponsePayload AddResponse handle(@RequestPayload AddRequest addRequest, @RequestPayload Element element, MessageContext messageContext) { //element:原始的XML報文 System.out.println(addRequest == null); System.out.println(addRequest.getUser().getUsername()); System.out.println(element.asXML()); AddResponse response = new AddResponse(); response.setSuccess(false); return response; } */ }

 

 客戶端(soupui)發送請求報文(soupui的使用能夠在網上找到):ide

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:user="http://localhost/ws/UserService">
   <soapenv:Header/>
   <soapenv:Body>
      <user:AddRequest>
         <user:User>
            <!--You may enter the following 2 items in any order-->
            <username>123</username>
            <password>123123123</password>
         </user:User>
      </user:AddRequest>
   </soapenv:Body>
</soapenv:Envelope>

下面是客戶端接收到的報文:ui

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Header/>
   <SOAP-ENV:Body>
      <ns3:AddResponse xmlns:ns3="http://localhost/ws/UserService">
         <success>true</success>
      </ns3:AddResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

先對上面註解代碼和請求報文和迴應報文解釋一下:this

  1. @Endpoint:是指消息的接收者,就是SpringWS的endpoint,能夠一個或者多個,關鍵是下面的註解。
  2. @PayloadRoot:是指soap消息中的須要被調用的方法,它包括兩個參數:localPart的值實質上就是請求報文中的一個節點(AddRequest),而namespace就是指我定義在Schema的命名空間。
  3. @RequestPayload:是指請求的實例。當客戶端發送消息過來,服務端接收到的實際是XML報文,在調用此方法以前,SpringWS已經幫咱們把XML序列化成實例了(咱們在以前已經生成對應的AddRequest和AddResponse等class,並指明命名空間)。
  4. @ResponsePayload:是指最終返回的實例,而客戶端最終也是以XML返回給客戶端。

 3、剩下的工做就是讓spring掃描註解,對spring-ws-servlet.xml進行修改:spa

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sws="http://www.springframework.org/schema/web-services" xmlns:int="http://www.springframework.org/schema/integration" xmlns:ws="http://www.springframework.org/schema/integration/ws" xmlns:util="http://www.springframework.org/schema/util" xmlns:context="http://www.springframework.org/schema/context" 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/integration/ws http://www.springframework.org/schema/integration/ws/spring-integration-ws-2.2.xsd http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-2.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.2.xsd">
    <!-- begin:(二)-入門 -->
    <context:component-scan base-package="ws.user.endpoint"/>
    <context:component-scan base-package="ws.user.model"/>
    <bean id="userServcie" class="ws.user.service.IUserServcieImpl"/>
    <!-- end:(二)-入門 -->
    <!-- begin:(一)-環境搭建 -->
    <sws:dynamic-wsdl id="UserService" portTypeName="UserServicePortType" targetNamespace="http://localhost/ws/UserService" locationUri="/service/user" serviceName="UserService">
        <sws:xsd location="/WEB-INF/xsd/UserService.xsd"/>
    </sws:dynamic-wsdl>
    <!-- end:(一)-環境搭建 -->
</beans>

 以上的內容就到這裏,源碼的下載地址沒變,有什麼問題歡迎經過郵件交流,謝謝。rest

相關文章
相關標籤/搜索