Springws 简明教程

Spring WS - First Application

让我们开始通过 Spring-WS 框架编写一个基于 SOAP 的实际 Web 服务。在我们开始使用 Spring-WS 框架编写第一个示例之前,我们必须确保 Spring-WS 环境已按照 Spring Web Services - Environment Setup 章节中的说明正确设置。我们假设读者对 Eclipse IDE 有基本的知识了解。

Let us start writing an actual SOAP based web service with Spring-WS Framework. Before we start writing our first example using the Spring-WS framework, we have to ensure that the Spring-WS environment is setup properly as explained in Spring Web Services - Environment Setup chapter. We are assuming that the readers have some basic working knowledge with the Eclipse IDE.

因此,让我们继续编写一个简单的 Spring WS 应用程序,该应用程序将公开一个 Web 服务方法,以在 HR 门户中预订假期。

Therefore, let us proceed to write a simple Spring WS Application which will expose a web service method to book a leave in an HR Portal.

Contract-first Approach

Spring-WS 使用合约优先的方法,这意味着我们应该在编写任何基于 JAVA 的实施代码之前准备好我们的 XML Structures 。我们定义一个 LeaveRequest 对象,该对象包含子对象 - Leave 和 Employee。

Spring-WS uses the Contract-first approach, which means we should have our XML Structures ready before writing any JAVA based implementation code. We are defining a LeaveRequest Object, which has sub-objects – Leave and Employee.

以下为所需的 XML 构造 -

Following are the required XML constructs −

Leave.xml

<Leave xmlns = "http://tutorialspoint.com/hr/schemas">
   <StartDate>2016-07-03</StartDate>
   <EndDate>2016-07-07</EndDate>
</Leave>

Employee.xml

<Employee xmlns = "http://tutorialspoint.com/hr/schemas">
   <Number>404</Number>
   <FirstName>Mahesh</FirstName>
   <LastName>Parashar</LastName>
</Employee>

LeaveRequest.xml

<LeaveRequest xmlns = "http://tutorialspoint.com/hr/schemas">
   <Leave>
      <StartDate>2016-07-03</StartDate>
      <EndDate>2016-07-07</EndDate>
   </Leave>

   <Employee>
      <Number>404</Number>
      <FirstName>Mahesh</FirstName>
      <LastName>Parashar</LastName>
   </Employee>
</LeaveRequest>

hr.xsd

<xs:schema xmlns:xs = "http://www.w3.org/2001/XMLSchema"
   xmlns:hr = "http://tutorialspoint.com/hr/schemas"
   elementFormDefault = "qualified"
   targetNamespace = "http://tutorialspoint.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>

Create the Project

现在,让我们打开一个命令控制台,转到 C:\MVN 目录并执行以下 mvn 命令。

Let us now open a command console, go the C:\MVN directory and execute the following mvn command.

C:\MVN>mvn archetype:generate -DarchetypeGroupId = org.springframework.ws
-DarchetypeArtifactId = spring-ws-archetype -DgroupId = com.tutorialspoint.hr
-DartifactId = leaveService

Maven 将开始处理并创建完整的 Java 应用程序项目结构。

Maven will start processing and will create the complete Java Application Project Structure.

[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] Using property: groupId = com.tutorialspoint.hr
[INFO] Using property: artifactId = leaveService
Define value for property 'version':  1.0-SNAPSHOT: :
[INFO] Using property: package = com.tutorialspoint.hr
Confirm properties configuration:
groupId: com.tutorialspoint.hr
artifactId: leaveService
version: 1.0-SNAPSHOT
package: com.tutorialspoint.hr
 Y: :
[INFO] -------------------------------------------------------------------------
---
[INFO] Using following parameters for creating project from Old (1.x) Archetype:
 spring-ws-archetype:2.0.0-M1
[INFO] -------------------------------------------------------------------------
---
[INFO] Parameter: groupId, Value: com.tutorialspoint.hr
[INFO] Parameter: packageName, Value: com.tutorialspoint.hr
[INFO] Parameter: package, Value: com.tutorialspoint.hr
[INFO] Parameter: artifactId, Value: leaveService
[INFO] Parameter: basedir, Value: C:\mvn
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] project created from Old (1.x) Archetype in dir: C:\mvn\leaveService
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 35.989 s
[INFO] Finished at: 2017-01-21T11:18:31+05:30
[INFO] Final Memory: 17M/178M
[INFO] ------------------------------------------------------------------------

现在,转至 C:/MVN 目录。我们会看到一个创建的 Java 应用程序项目,该项目名为 leaveService (如 artifactId 中所指定)。更新 pom.xml 并将 HumanResourceService.java 和 HumanResourceServiceImpl.java 添加到以下文件夹中——C:\MVN\leaveService\src\main\java\com\tutorialspoint\hr\service 文件夹。完成后,将 LeaveEndpoint.java 添加到以下文件夹中——C:\MVN\leaveService\src\main\java\com\tutorialspoint\hr\ws 文件夹。

Now go to C:/MVN directory. We will see a java application project created named leaveService (as specified in artifactId). Update the pom.xml and add HumanResourceService.java and HumanResourceServiceImpl.java in the following folder – C:\MVN\leaveService\src\main\java\com\tutorialspoint\hr\service folder. Once that is done, then add LeaveEndpoint.java in the following folder – C:\MVN\leaveService\src\main\java\com\tutorialspoint\hr\ws folder.

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/maven-v4_0_0.xsd">

   <modelVersion>4.0.0</modelVersion>
   <groupId>com.tutorialspoint.hr</groupId>
   <artifactId>leaveService</artifactId>
   <packaging>war</packaging>
   <version>1.0-SNAPSHOT</version>
   <name>leaveService Spring-WS Application</name>
   <url>http://www.springframework.org/spring-ws</url>

   <build>
      <finalName>leaveService</finalName>
   </build>

   <dependencies>
      <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>
</project>

HumanResourceService.java

package com.tutorialspoint.hr.service;

import java.util.Date;

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

HumanResourceServiceImpl.java

package com.tutorialspoint.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.tutorialspoint.hr.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.tutorialspoint.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 = "http://tutorialspoint.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.tutorialspoint.hr"/>
   <bean id = "humanResourceService"
      class = "com.tutorialspoint.hr.service.HumanResourceServiceImpl" />
   <sws:annotation-driven/>

   <sws:dynamic-wsdl id = "leave"
      portTypeName = "HumanResource"
      locationUri = "/leaveService/"
      targetNamespace = "http://tutorialspoint.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>TutorialsPoint 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

<xs:schema xmlns:xs = "http://www.w3.org/2001/XMLSchema"
   xmlns:hr = "http://tutorialspoint.com/hr/schemas"
   elementFormDefault = "qualified"
   targetNamespace = "http://tutorialspoint.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>

Build the Project

现在,让我们打开命令控制台,转到 C:\MVN\leaveService 目录并执行以下 mvn 命令。

Let us now open the command console, go the C:\MVN\leaveService directory and execute the following mvn command.

C:\MVN\leaveService>mvn clean package

Maven 将开始构建该项目。

Maven will start building the project.

[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building leaveService Spring-WS Application 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ leaveService ---
[INFO] Deleting C:\mvn\leaveService\target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ leaveServi
ce ---
[WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources,
i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ leaveService --
-
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding Cp1252, i.e. b
uild is platform dependent!
[INFO] Compiling 3 source files to C:\mvn\leaveService\target\classes
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ le
aveService ---
[WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources,
i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory C:\mvn\leaveService\src\test\resource
s
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ leaveSe
rvice ---
[INFO] No sources to compile
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ leaveService ---
[INFO] No tests to run.
[INFO]
[INFO] --- maven-war-plugin:2.2:war (default-war) @ leaveService ---
[INFO] Packaging webapp
[INFO] Assembling webapp [leaveService] in [C:\mvn\leaveService\target\leaveServ
ice]
[INFO] Processing war project
[INFO] Copying webapp resources [C:\mvn\leaveService\src\main\webapp]
[INFO] Webapp assembled in [7159 msecs]
[INFO] Building war: C:\mvn\leaveService\target\leaveService.war
[INFO] WEB-INF\web.xml already added, skipping
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 19.667 s
[INFO] Finished at: 2017-01-21T11:56:43+05:30
[INFO] Final Memory: 18M/173M
[INFO] ------------------------------------------------------------------------

Import Project in Eclipse

按照以下步骤导入 Eclipse 中的项目。

Follow the steps given below to import the project in Eclipse.

  1. Open Eclipse.

  2. Select File → Import → option.

  3. Select Maven Projects Option. Click on Next Button.

  4. Select Project location, where leaveService project was created using Maven.

  5. Click Finish Button.

Run the Project

完成创建源文件和配置文件后,导出应用程序。右键单击应用程序,使用 Export → WAR File 选项,并将 leaveService.war 文件保存到 Tomcat 的 webapps 文件夹中。

Once we are done with creating source and configuration files, export the application. Right click on the application, use Export → WAR File option and save the leaveService.war file in Tomcat’s webapps folder.

启动 Tomcat 服务器,并确保我们可以使用标准浏览器,从 webapps 文件夹访问其他网页。尝试访问 URL – [role="bare"] [role="bare"]http://localhost:8080/leaveService/leave.wsdl ,如果 Spring Web 应用程序一切正常,我们应会看到以下屏幕。

Start the Tomcat server and ensure we are able to access other webpages from the webapps folder using a standard browser. Try to access the URL – [role="bare"]http://localhost:8080/leaveService/leave.wsdl, if everything is ok with the Spring Web Application, we should see the following screen.

first application result