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。