Spring Boot的简单性快速创建SOAP Web服务
目录
1.技术堆栈
2.项目结构
3.创建Spring Boot项目
4.创建SOAP域并生成Java代码
5.创建SOAP WS端点
6.添加配置Bean
7.演示
8.摘要
1.技术栈
- JDK 1.8,Eclipse,Maven –开发环境
- 春季启动–基础应用程序框架
- wsdl4j –用于为我们的服务发布WSDL
- SOAP-UI –用于测试我们的服务
- JAXB maven插件 –用于代码生成
2.项目结构
为该演示创建的类和文件如下所示。
3.创建Spring Boot项目
仅从SPRING INITIALIZR站点创建具有Web Services
依赖项的spring boot项目。选择依赖项并提供适当的Maven GAV坐标后,以压缩格式下载项目。解压缩,然后将eclipse中的项目导入为maven项目。
生成Spring启动项目
添加Wsdl4j依赖关系
编辑pom.xml
此依赖关系并将其添加到您的项目中。
<dependency>
<groupId>wsdl4j</groupId>
<artifactId>wsdl4j</artifactId>
</dependency>
4.创建SOAP域模型并生成Java代码
当我们遵循合同优先的方法来开发服务时,我们需要首先为我们的服务创建域(方法和参数)。为简单起见,我们将请求和响应都保留在同一个XSD中,但是在实际的企业用例中,我们将有多个XSD相互导入以形成最终定义。
student.xsd
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="https://www.howtodoinjava.com/xml/school"
targetNamespace="https://www.howtodoinjava.com/xml/school" elementFormDefault="qualified">
<xs:element name="StudentDetailsRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="StudentDetailsResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="Student" type="tns:Student"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="Student">
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="standard" type="xs:int"/>
<xs:element name="address" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
将以上文件放在resources
项目的文件夹中。
将XSD的JAXB maven插件添加到Java对象生成
我们将使用它jaxb2-maven-plugin
来高效地生成域类。现在,我们需要将以下Maven插件添加到项目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模式文件编译为完全注释的Java类。
现在执行上面的maven插件以从XSD生成Java代码。
5.创建SOAP Web服务端点
StudentEndpoint
类将处理对服务的所有传入请求,并将调用委派给数据存储库的finder方法。
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 = "https://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;
}
}
这里有一些关于注释的细节–
@Endpoint
向Spring WS注册该类,作为处理传入SOAP消息的潜在候选者。@PayloadRoot
然后由WS使用WS根据消息的名称空间和localPart选择处理程序方法。请注意此注释中提到的命名空间URL和请求有效负载根请求。@RequestPayload
指示传入的消息将被映射到方法的request参数。- 该
@ResponsePayload
注解使得春季WS映射返回值来响应有效载荷
Create Data Repository:
如前所述,我们将使用硬编码数据作为此演示的后端,让我们添加一个StudentRepository.java
带有Spring @Repository
注释的类。它只会保存数据,HashMap
并且还会提供一种称为的查找器方法findStudent()
。
package com.example.howtodoinjava.springbootsoapservice;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.PostConstruct;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import com.howtodoinjava.xml.school.Student;
@Component
public class StudentRepository {
private static final Map<String, Student> students = new HashMap<>();
@PostConstruct
public void initData() {
Student student = new Student();
student.setName("Sajal");
student.setStandard(5);
student.setAddress("Pune");
students.put(student.getName(), student);
student = new Student();
student.setName("Kajal");
student.setStandard(5);
student.setAddress("Chicago");
students.put(student.getName(), student);
student = new Student();
student.setName("Lokesh");
student.setStandard(6);
student.setAddress("Delhi");
students.put(student.getName(), student);
student = new Student();
student.setName("Sukesh");
student.setStandard(7);
student.setAddress("Noida");
students.put(student.getName(), student);
}
public Student findStudent(String name) {
Assert.notNull(name, "The Student's name must not be null");
return students.get(name);
}
}
6.添加SOAP Web服务配置Bean
创建带有@Configuration
注释的类以保存bean定义。
package com.example.howtodoinjava.springbootsoapservice;
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 Config extends WsConfigurerAdapter
{
@Bean
public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext)
{
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
servlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean(servlet, "/service/*");
}
@Bean(name = "studentDetailsWsdl")
public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema countriesSchema)
{
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("StudentDetailsPort");
wsdl11Definition.setLocationUri("/service/student-details");
wsdl11Definition.setTargetNamespace("https://www.howtodoinjava.com/xml/school");
wsdl11Definition.setSchema(countriesSchema);
return wsdl11Definition;
}
@Bean
public XsdSchema countriesSchema()
{
return new SimpleXsdSchema(new ClassPathResource("school.xsd"));
}
}
Config
类扩展WsConfigurerAdapter
,用于配置注释驱动的Spring-WS编程模型。MessageDispatcherServlet
– Spring-WS使用它来处理SOAP请求。我们需要注入ApplicationContext
该servlet,以便Spring-WS找到其他bean。它还声明了请求的URL映射。DefaultWsdl11Definition
使用公开标准的WSDL 1.1XsdSchema
。Bean名称studentDetailsWsdl
将是将公开的wsdl名称。将在下提供http://localhost:8080/service/studentDetailsWsdl.wsdl
。这是在春季首先公开合约wsdl的最简单方法。此配置还在
servlet.setTransformWsdlLocations( true )
内部使用WSDL位置servlet转换。如果我们看到导出的WSDL,soap:address
则将具有localhost
地址。同样,如果我们改为从分配给已部署计算机的面向公众的IP地址访问WSDL,则将看到该地址,而不是localhost
。因此,端点URL根据部署环境是动态的。
7. Spring Boot SOAP Web服务演示
mvn clean install
使用以下java -jar target\spring-boot-soap-service-0.0.1-SNAPSHOT.jar
命令进行maven构建并使用命令启动应用程序。这将在默认端口中启动一台tomcat服务器,8080
并将在其中部署应用程序。
1)现在去http://localhost:8080/service/studentDetailsWsdl.wsdl
查看WSDL是否正常。
WSDL生成
2)一旦成功生成了WSDL,就可以使用该WSDL在SOAP ui中创建一个项目并测试该应用程序。样品请求和响应如下。
在postman里也可以测试
请求:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sch="https://www.howtodoinjava.com/xml/school">
<soapenv:Header/>
<soapenv:Body>
<sch:StudentDetailsRequest>
<sch:name>Sajal</sch:name>
</sch:StudentDetailsRequest>
</soapenv:Body>
</soapenv:Envelope>
响应:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<ns2:StudentDetailsResponse xmlns:ns2="https://www.howtodoinjava.com/xml/school">
<ns2:Student>
<ns2:name>Sajal</ns2:name>
<ns2:standard>5</ns2:standard>
<ns2:address>Pune</ns2:address>
</ns2:Student>
</ns2:StudentDetailsResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
SOAP UI示例
8.总结
在上面的示例中,我们学习了使用Spring Boot创建SOAP Web服务。我们还学会了从WSDL生成Java代码。我们了解了处理SOAP请求所需的bean。