虽然目前REST和微服务越来越流行,但是SOAP在某些情况下,仍然有它的用武之地;
在本篇 spring boot SOAP教程中,我们会专注于和Spring boot相关的配置,感受下在Spring Boot中,创建SOAP webservice是如何的简便、快速;
本文将以一个"学生搜索"这个小功能作为示例,演示Spring Boot中SOAP webservice的创建过程;
技术栈JDK 1.8, Eclipse, Maven – 开发环境
Spring-boot – 基础开发框架
wsdl4j – 发布WSDL
SOAP-UI – 测试服务
JAXB maven plugin - 代码生成
工程结构本工程的代码及文件目录结构如下
访问 SPRING INITIALIZR网站,添加Web Services依赖,输入maven的GAV 坐标,点击下载工程,下载完成后解压导入IDE即可;
修改pom.xml文件,添加Wsdl4j依赖: <dependency> <groupId>wsdl4j</groupId> <artifactId>wsdl4j</artifactId> </dependency> 创建SOAP Domain模型并生成Java代码
首先,我们需要给我们的服务创建domain(方法和参数),出于简便考虑,我将请求和响应放在了同一个XSD文件里,不过在实际应用开发的时候,通常需要放到多个XSD文件里;
创建student.xsd文件,并放到我们工程的resources 目录下
student.xsd
我们将使用jaxb2-maven-plugin来高效的生成domain代码,首先需要在pom.xml文件添加以下插件配置代码:
<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>该插件将使用 XJC工具作为代码生成引擎,XJC能将XML schema 文件转成带注解的代码;
现在,我们就可以执行以上插件生成代码了;
StudentEndpoint类会处理所有访问该服务的请求,并委派给StudentRepository去处理,具体代码如下:
package com.example.howtodoinjava.springbootsoapservice; 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.howtodoinjava.xml.school.StudentDetailsRequest; import com.howtodoinjava.xml.school.StudentDetailsResponse; @Endpoint public class StudentEndpoint { private static final String NAMESPACE_URI = "http://www.howtodoinjava.com/xml/school"; private StudentRepository StudentRepository; @Autowired public StudentEndpoint(StudentRepository StudentRepository) { this.StudentRepository = StudentRepository; } @PayloadRoot(namespace = NAMESPACE_URI, localPart = "StudentDetailsRequest") @ResponsePayload public StudentDetailsResponse getStudent(@RequestPayload StudentDetailsRequest request) { StudentDetailsResponse response = new StudentDetailsResponse(); response.setStudent(StudentRepository.findStudent(request.getName())); return response; } }对上面的几个注解做个简单说明(可以和Spring MVC的Controller做个类比,有点相似):
@Endpoint 声明用于处理SOAP消息
@PayloadRoot 根据namespace和localPart映射对应的处理方法
@RequestPayload 声明进来的消息将会与该方法的参数映射
@ResponsePayload 方法返回值的映射
创建Data Repository