Spring Boot SOAP Web服务示例

时间:2020-02-23 14:35:49  来源:igfitidea点击:

在本教程中,我们将看到如何使用Spring Boot创建SOAP Web服务。

我们将使用Spring Boot创建合同First SOAP Web服务。
我们将专注于如何定义SOAP Web服务的配置。

使用的工具

  • JDK 1.8,Eclipse,Maven
  • Spring boot - 基础应用程序框架
  • WSDL4J - 用于为我们的服务发布WSDL
  • JAXB Maven插件 - 用于代码生成
  • SOAP-UI - 用于测试我们的SOAP Web服务

项目结构

让我们创建一个简单的Spring启动应用程序。

第1步:转到"https://start.spring.io/"并根据下面的屏幕截图创建Spring启动项目。

第2步:在Eclipse中导入Maven项目。

添加WSDL4J依赖项

步骤3:将WSDL4J依赖添加到POM。

<dependency>
			<groupId>wsdl4j</groupId>
			<artifactId>wsdl4j</artifactId>
	</dependency>

XSD文件定义域

步骤4:在资源文件夹中创建名为"book.xsd"的XSD文件。
正如我们创建合同的第一个SOAP Web服务,我们需要定义Spring-WS将自动导出为WSDL的XML模式文件(XSD)。

我们正在创建Book.xsd,它将使用其ID,标题和页数返回书籍。

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
	xmlns:tns="https://www.theitroad.com/xml/book" targetNamespace="https://www.theitroad.com/xml/book"
	elementFormDefault="qualified">
 
	<xs:element name="getBookRequest">
		<xs:complexType>
			<xs:sequence>
				<xs:element name="id" type="xs:int" 
			</xs:sequence>
		</xs:complexType>
	</xs:element>
 
	<xs:element name="getBookResponse">
		<xs:complexType>
			<xs:sequence>
				<xs:element name="Book" type="tns:Book" 
			</xs:sequence>
		</xs:complexType>
	</xs:element>
 
	<xs:complexType name="Book">
		<xs:sequence>
			<xs:element name="id" type="xs:int" 
			<xs:element name="title" type="xs:string" 
			<xs:element name="pages" type="xs:long" 
		</xs:sequence>
	</xs:complexType>
 
</xs:schema>

基于XSD生成域类

步骤5:我们现在将基于XSD生成域类。
我们将使用JAXB Maven插件基于XSD生成域类。

用于Maven的插件配置

<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
			<plugin>
				<groupId>org.codehaus.mojo</groupId>
				<artifactId>jaxb2-maven-plugin</artifactId>
				<version>1.6</version>
				<executions>
					<execution>
						<id>xjc</id>
						<goals>
							<goal>xjc</goal>
						</goals>
					</execution>
				</executions>
				<configuration>
					<schemaDirectory>${project.basedir}/src/main/resources/</schemaDirectory>
					<outputDirectory>${project.basedir}/src/main/java</outputDirectory>
					<clearOutputDir>false</clearOutputDir>
				</configuration>
			</plugin>

因此,当我们运行Maven Build时,将生成这些域类。

创建带有虚拟数据的书籍存储库

步骤6:创建BookRepository.java.This存储库将为Web服务提供伪数据。

package org.igi.theitroad;
 
import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;
 
 
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
 
import com.theitroad.xml.book.Book;
 
@Component
public class BookRepository {
	private static final Map<Integer, Book> books = new HashMap<>();
 
	@PostConstruct
	public void initData() {
		
		Book javaBook = new Book();
		javaBook.setId(1);
		javaBook.setTitle("Head first java");
		javaBook.setPages(400);
		books.put(javaBook.getId(), javaBook);
		
		Book springBook = new Book();
		springBook.setId(2);
		springBook.setTitle("Spring in action");
		springBook.setPages(400);
		books.put(springBook.getId(), springBook);
		
		Book pythonBook = new Book();
		pythonBook.setId(3);
		pythonBook.setTitle("Learning Python");
		pythonBook.setPages(400);
		books.put(pythonBook.getId(), pythonBook);
		
		Book hiberanteBook = new Book();
		hiberanteBook.setId(4);
		hiberanteBook.setTitle("Hibernate in action");
		hiberanteBook.setPages(400);
		books.put(hiberanteBook.getId(), hiberanteBook);
	}
 
	public Book findBookById(int id) {
		Assert.notNull(id, "The book's name must not be null");
		return books.get(id);
	}
}

定义书籍服务端点

步骤7:要创建书籍服务端点,我们只需用Spring Ws注释向Pojo注释为处理SOAP请求。

package org.igi.theitroad;
 
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 org.springframework.ws.server.endpoint.annotation.ResponsePayload;
 
import com.theitroad.xml.book.GetBookRequest;
import com.theitroad.xml.book.GetBookResponse;
 
@Endpoint
public class BookEndpoint {
	private static final String NAMESPACE_URI = "https://www.theitroad.com/xml/book";
 
	private BookRepository bookRepository;
 
	@Autowired
	public BookEndpoint(BookRepository bookRepository) {
		this.bookRepository = bookRepository;
	}
 
	@PayloadRoot(namespace = NAMESPACE_URI, localPart = "getBookRequest")
	@ResponsePayload
	public GetBookResponse getCountry(@RequestPayload GetBookRequest request) {
		GetBookResponse response = new GetBookResponse();
		response.setBook(bookRepository.findBookById(request.getId()));
		return response;
	}
}

让我们查看有关上述注释的更多详细信息。
@endpoint:此注释用于注册带有Spring WS的类,用于处理传入的SOAP请求。
@PayLoadRoot:此注释可帮助Spring WS根据消息的命名空间和LocalPart选择处理程序方法。
@ResponsePayload:此注释表示传入消息将映射到方法的请求参数。
@ResponsePayload:此注释用于Spring WS将返回值映射到响应有效载荷。

定义Web服务配置

第8步:创建一个名为WebServiceConfiguration.java的新类,其中包含Spring Web服务相关的Bean配置。

package org.igi.theitroad;
 
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.ws.config.annotation.EnableWs;
import org.springframework.ws.config.annotation.WsConfigurerAdapter;
import org.springframework.ws.transport.http.MessageDispatcherServlet;
import org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition;
import org.springframework.xml.xsd.SimpleXsdSchema;
import org.springframework.xml.xsd.XsdSchema;
 
@EnableWs
@Configuration
public class WebServiceConfiguration extends WsConfigurerAdapter {
	@Bean
	public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
		MessageDispatcherServlet servlet = new MessageDispatcherServlet();
		servlet.setApplicationContext(applicationContext);
		servlet.setTransformWsdlLocations(true);
		return new ServletRegistrationBean(servlet, "/ws/*");
	}
 
	@Bean(name = "booksWsdl")
	public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema booksSchema) {
		DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
		wsdl11Definition.setPortTypeName("BooksPort");
		wsdl11Definition.setLocationUri("/ws");
		wsdl11Definition.setTargetNamespace("https://www.theitroad.com/xml/book");
		wsdl11Definition.setSchema(booksSchema);
		return wsdl11Definition;
	}
 
	@Bean
	public XsdSchema booksSchema() {
		return new SimpleXsdSchema(new ClassPathResource("book.xsd"));
	}
}

Spring WS使用MessageSispatcherServlet处理SOAP消息。
设置ApplicationContext非常重要,否则Spring Ws将无法自动检测Spring Bean。
defaultwsdl11definition使用xsdschema公开标准wsdl。

请注意,DefaultWSDL11Definition for DefaultWSDL11Definition的Bean名称为WSDL定义URL,因此具有上述配置的WSDL URL将为http://localhost:8080/ws/bookswsdl.wsdl。

步骤9:创建名为"springbootoapexampleapplication.java"的主java类,这将具有主要方法。

package org.igi.theitroad;
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
 
@SpringBootApplication
public class SpringBootSoapExampleApplication {
 
	public static void main(String[] args) {
		SpringApplication.run(SpringBootSoapExampleApplication.class, args);
	}
}

运行应用程序

步骤10:运行应用程序在运行上面的应用程序时,我们将得到以下输出:

...
...
2016-09-16 20:30:37.597 INFO 24898 — [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-09-16 20:30:38.157 INFO 24898 — [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2016-09-16 20:30:38.348 INFO 24898 — [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path "
2016-09-16 20:30:38.355 INFO 24898 — [ main] o.a.j.SpringBootSoapExampleApplication : Started SpringBootSoapExampleApplication in 11.127 seconds (JVM running for 14.293)

测试WSDL URL.

步骤11:检查WSDL URL。

URL:http://localhost:8080/ws/bookswsdl.wsdl点击上述URL,我们将得到以下WSDL文件。

<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
	xmlns:sch="https://www.theitroad.com/xml/book" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
	xmlns:tns="https://www.theitroad.com/xml/book" targetNamespace="https://www.theitroad.com/xml/book">
	<wsdl:types>
		<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
			elementFormDefault="qualified" targetNamespace="https://www.theitroad.com/xml/book">
			<xs:element name="getBookRequest">
				<xs:complexType>
					<xs:sequence>
						<xs:element name="id" type="xs:int" 
					</xs:sequence>
				</xs:complexType>
			</xs:element>
			<xs:element name="getBookResponse">
				<xs:complexType>
					<xs:sequence>
						<xs:element name="Book" type="tns:Book" 
					</xs:sequence>
				</xs:complexType>
			</xs:element>
			<xs:complexType name="Book">
				<xs:sequence>
					<xs:element name="id" type="xs:int" 
					<xs:element name="title" type="xs:string" 
					<xs:element name="pages" type="xs:long" 
				</xs:sequence>
			</xs:complexType>
		</xs:schema>
	</wsdl:types>
	<wsdl:message name="getBookRequest">
		<wsdl:part element="tns:getBookRequest" name="getBookRequest">
		</wsdl:part>
	</wsdl:message>
	<wsdl:message name="getBookResponse">
		<wsdl:part element="tns:getBookResponse" name="getBookResponse">
		</wsdl:part>
	</wsdl:message>
	<wsdl:portType name="BooksPort">
		<wsdl:operation name="getBook">
			<wsdl:input message="tns:getBookRequest" name="getBookRequest">
			</wsdl:input>
			<wsdl:output message="tns:getBookResponse" name="getBookResponse">
			</wsdl:output>
		</wsdl:operation>
	</wsdl:portType>
	<wsdl:binding name="BooksPortSoap11" type="tns:BooksPort">
		<soap:binding style="document"
			transport="http://schemas.xmlsoap.org/soap/http" 
		<wsdl:operation name="getBook">
			<soap:operation soapAction="" 
			<wsdl:input name="getBookRequest">
				<soap:body use="literal" 
			</wsdl:input>
			<wsdl:output name="getBookResponse">
				<soap:body use="literal" 
			</wsdl:output>
		</wsdl:operation>
	</wsdl:binding>
	<wsdl:service name="BooksPortService">
		<wsdl:port binding="tns:BooksPortSoap11" name="BooksPortSoap11">
			<soap:address location="http://localhost:8080/ws" 
		</wsdl:port>
	</wsdl:service>
</wsdl:definitions>

测试SpringSOAP Web服务

步骤11:SOAP UI上的测试应用程序在SOAP UI上使用上述WSDL文件创建一个项目并测试应用程序。
SOAP请求

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:book="https://www.theitroad.com/xml/book">
   <soapenv:Header
   <soapenv:Body>
      <book:getBookRequest>
         <book:id>3</book:id>
      </book:getBookRequest>
   </soapenv:Body>
</soapenv:Envelope>

SOAP响应

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Header
   <SOAP-ENV:Body>
      <ns2:getBookResponse xmlns:ns2="https://www.theitroad.com/xml/book">
         <ns2:Book>
            <ns2:id>3</ns2:id>
            <ns2:title>Learning Python</ns2:title>
            <ns2:pages>400</ns2:pages>
         </ns2:Book>
      </ns2:getBookResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>