Spring WS入門程式


在這一章節中,我們將使用Spring-WS框架編寫一個基於SOAP的Web服務。 在開始使用Spring-WS框架編寫第一個範例應用之前,必須確保Spring-WS環境的設定正確,正如Spring Web Services環境設定章節中所述。並假設讀者對Eclipse IDE有一些基本的工作知識。

下面開始編寫一個簡單的Spring WS應用程式,這個應用程式將公開Web服務方法以在HR入口中預訂假期。

契約優先方法

Spring-WS使用契約優先方法,因此在編寫基於JAVA的實現程式碼之前,我們應該準備好XML結構。 下面定義一個包含子物件 - LeaveEmployeeLeaveRequest物件。

以下是所需的XML結構 -

檔案:WEB-INF/Leave.xml 的內容如下所示 -

<Leave xmlns = "https://www.tw511.com/hr/schemas">
   <StartDate>2018-07-03</StartDate>
   <EndDate>2018-07-30</EndDate>
</Leave>

檔案:WEB-INF/Employee.xml 的內容如下所示 -

<Employee xmlns = "https://www.tw511.com/hr/schemas">
   <Number>10910</Number>
   <FirstName>Max</FirstName>
   <LastName>Su</LastName>
</Employee>

檔案:WEB-INF/LeaveRequest.xml 的內容如下所示 -

<LeaveRequest xmlns = "https://www.tw511.com/hr/schemas">
   <Leave>
      <StartDate>2018-07-03</StartDate>
      <EndDate>2018-07-30</EndDate>
   </Leave>

   <Employee>
      <Number>10010</Number>
      <FirstName>Max</FirstName>
      <LastName>Su</LastName>
   </Employee>
</LeaveRequest>

檔案:WEB-INF/hr.xsd 的內容如下所示 -

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs = "http://www.w3.org/2001/XMLSchema"
   xmlns:hr = "https://www.tw511.com/hr/schemas"
   elementFormDefault = "qualified"
   targetNamespace = "https://www.tw511.com/hr/schemas">

   <xs:element name = "LeaveRequest">
      <xs:complexType>
         <xs:all>
            <xs:element name = "Leave" type = "hr:LeaveType"/>
            <xs:element name = "Employee" type = "hr:EmployeeType"/>
         </xs:all>
      </xs:complexType>
   </xs:element>

   <xs:complexType name = "LeaveType">
      <xs:sequence>
         <xs:element name = "StartDate" type = "xs:date"/>
         <xs:element name = "EndDate" type = "xs:date"/>
      </xs:sequence>
   </xs:complexType>

   <xs:complexType name = "EmployeeType">
      <xs:sequence>
         <xs:element name = "Number" type = "xs:integer"/>
         <xs:element name = "FirstName" type = "xs:string"/>
         <xs:element name = "LastName" type = "xs:string"/>
      </xs:sequence>
   </xs:complexType>
</xs:schema>

建立專案

現在開啟Eclipse,從選單中找到:檔案 -> New -> Maven Project, 開啟介面如下所示:

進入下一步,選擇 maven-archetype-webapp,如下所示:

填寫專案相關資訊(可根據你的實際情況填寫),如下所示 -

完整的專案目錄結構如下圖所示 -

以下是各個檔案中的程式碼 -

檔案:pom.xml -

<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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.yiibai</groupId>
    <artifactId>leaveService</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>leaveService Maven Webapp</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.ws</groupId>
            <artifactId>spring-ws-core</artifactId>
            <version>2.4.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>jdom</groupId>
            <artifactId>jdom</artifactId>
            <version>1.0</version>
        </dependency>

        <dependency>
            <groupId>jaxen</groupId>
            <artifactId>jaxen</artifactId>
            <version>1.1</version>
        </dependency>

        <dependency>
            <groupId>wsdl4j</groupId>
            <artifactId>wsdl4j</artifactId>
            <version>1.6.2</version>
        </dependency>
    </dependencies>

    <build>
        <finalName>leaveService</finalName>
        <defaultGoal>compile</defaultGoal>
    </build>
</project>

檔案:HumanResourceService.java -

package com.yiibai.hr.service;

import java.util.Date;

public interface HumanResourceService {
    void bookLeave(Date startDate, Date endDate, String name);
}

檔案:HumanResourceServiceImpl.java -

package com.yiibai.hr.service;

import java.util.Date;
import org.springframework.stereotype.Service;

@Service
public class HumanResourceServiceImpl implements HumanResourceService {
   public void bookLeave(Date startDate, Date endDate, String name) {
      System.out.println("Booking holiday for [" + startDate + "-" + endDate + "] for [" + name + "] ");
   }
}

檔案:LeaveEndpoint.java -

package com.yiibai.ws;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
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 com.yiibai.hr.service.HumanResourceService;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.Namespace;
import org.jdom.xpath.XPath;

@Endpoint
public class LeaveEndpoint {
   private static final String NAMESPACE_URI = "https://www.tw511.com/hr/schemas";
   private XPath startDateExpression;
   private XPath endDateExpression;
   private XPath nameExpression;
   private HumanResourceService humanResourceService;

   @Autowired
   public LeaveEndpoint(HumanResourceService humanResourceService) throws JDOMException {
      this.humanResourceService = humanResourceService;

      Namespace namespace = Namespace.getNamespace("hr", NAMESPACE_URI);

      startDateExpression = XPath.newInstance("//hr:StartDate");
      startDateExpression.addNamespace(namespace);

      endDateExpression = XPath.newInstance("//hr:EndDate");
      endDateExpression.addNamespace(namespace);

      nameExpression = XPath.newInstance("concat(//hr:FirstName,' ',//hr:LastName)");
      nameExpression.addNamespace(namespace);
   }

   @PayloadRoot(namespace = NAMESPACE_URI, localPart = "LeaveRequest")                  
   public void handleLeaveRequest(@RequestPayload Element leaveRequest) throws Exception {
      SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
      Date startDate = dateFormat.parse(startDateExpression.valueOf(leaveRequest));
      Date endDate = dateFormat.parse(endDateExpression.valueOf(leaveRequest));
      String name = nameExpression.valueOf(leaveRequest);

      humanResourceService.bookLeave(startDate, endDate, name);
   }
}

檔案:/WEB-INF/spring-ws-servlet.xml -

<beans xmlns = "http://www.springframework.org/schema/beans"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xmlns:context = "http://www.springframework.org/schema/context"
   xmlns:sws = "http://www.springframework.org/schema/web-services"
   xsi:schemaLocation = "http://www.springframework.org/schema/beans

   http://www.springframework.org/schema/beans/spring-beans-3.0.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/context 
   http://www.springframework.org/schema/context/spring-context-3.0.xsd">

   <context:component-scan base-package = "com.yiibai.hr"/>
   <bean id = "humanResourceService"
      class = "com.yiibai.hr.service.HumanResourceServiceImpl" />
   <sws:annotation-driven/>

   <sws:dynamic-wsdl id = "leave"
      portTypeName = "HumanResource"
      locationUri = "/leaveService/"
      targetNamespace = "https://www.tw511.com/hr/definitions">
      <sws:xsd location = "/WEB-INF/hr.xsd"/>
   </sws:dynamic-wsdl>
</beans>

檔案:/WEB-INF/web.xml -

<web-app 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"
   version = "2.4">

   <display-name>Yiibai HR Leave Service</display-name>
   <servlet>
      <servlet-name>spring-ws</servlet-name>
      <servlet-class>
         org.springframework.ws.transport.http.MessageDispatcherServlet
      </servlet-class>
      <init-param>
         <param-name>transformWsdlLocations</param-name>
         <param-value>true</param-value>
      </init-param>
   </servlet>

   <servlet-mapping>
      <servlet-name>spring-ws</servlet-name>
      <url-pattern>/*</url-pattern>
   </servlet-mapping>
</web-app>

檔案:/WEB-INF/hr.xsd -

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs = "http://www.w3.org/2001/XMLSchema"
   xmlns:hr = "https://www.tw511.com/hr/schemas"
   elementFormDefault = "qualified"
   targetNamespace = "https://www.tw511.com/hr/schemas">

   <xs:element name = "LeaveRequest">
      <xs:complexType>
         <xs:all>
            <xs:element name = "Leave" type = "hr:LeaveType"/>
            <xs:element name = "Employee" type = "hr:EmployeeType"/>
         </xs:all>
      </xs:complexType>
   </xs:element>

   <xs:complexType name = "LeaveType">
      <xs:sequence>
         <xs:element name = "StartDate" type = "xs:date"/>
         <xs:element name = "EndDate" type = "xs:date"/>
      </xs:sequence>
   </xs:complexType>

   <xs:complexType name = "EmployeeType">
      <xs:sequence>
         <xs:element name = "Number" type = "xs:integer"/>
         <xs:element name = "FirstName" type = "xs:string"/>
         <xs:element name = "LastName" type = "xs:string"/>
      </xs:sequence>
   </xs:complexType>
</xs:schema>

執行專案

當完成建立原始檔和組態檔案,使用Maven構建應用程式。 右鍵單擊應用程式專案名稱,在彈出的選單中選擇:Run As -> Maven Build… ,如下所示 -

構建成功後, 右鍵單擊應用程式專案名稱,在彈出的選單中選擇:Run As -> Run On Server… ,如下所示 -

Eclipse啟動Tomcat伺服器後, 嘗試存取URL => http://localhost:8080/leaveService/leave.wsdl,如果Spring Web應用程式一切正常,應該看到以下輸出結果 -