Spring Boot SOAP Webservice例子

前言

本文將學習如何利用Spring boot快速建立SOAP webservice服務;java

雖然目前REST和微服務愈來愈流行,可是SOAP在某些狀況下,仍然有它的用武之地;web

在本篇 spring boot SOAP教程中,咱們會專一於和Spring boot相關的配置,感覺下在Spring Boot中,建立SOAP webservice是如何的簡便、快速;spring

本文將以一個"學生搜索"這個小功能做爲示例,演示Spring Boot中SOAP webservice的建立過程;編程

技術棧

  • JDK 1.8, Eclipse, Maven – 開發環境
  • Spring-boot – 基礎開發框架
  • wsdl4j – 發佈WSDL
  • SOAP-UI – 測試服務
  • JAXB maven plugin - 代碼生成

工程結構

本工程的代碼及文件目錄結構以下
filetomcat

建立Spring Boot工程

訪問 SPRING INITIALIZR網站,添加Web Services依賴,輸入maven的GAV 座標,點擊下載工程,下載完成後解壓導入IDE便可;
file
修改pom.xml文件,添加Wsdl4j依賴:springboot

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

建立SOAP Domain模型並生成Java代碼

首先,咱們須要給咱們的服務建立domain(方法和參數),出於簡便考慮,我將請求和響應放在了同一個XSD文件裏,不過在實際應用開發的時候,一般須要放到多個XSD文件裏;app

建立student.xsd文件,並放到咱們工程的resources 目錄下
student.xsd框架

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.howtodoinjava.com/xml/school"
targetNamespace="http://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>

添加JAXB maven插件用於生成代碼

咱們將使用jaxb2-maven-plugin來高效的生成domain代碼,首先須要在pom.xml文件添加如下插件配置代碼:dom

<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 文件轉成帶註解的代碼;
如今,咱們就能夠執行以上插件生成代碼了;maven

建立SOAP Webservice Endpoint

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作個類比,有點類似):

  1. @Endpoint 聲明用於處理SOAP消息
  2. @PayloadRoot 根據namespace和localPart映射對應的處理方法
  3. @RequestPayload 聲明進來的消息將會與該方法的參數映射
  4. @ResponsePayload 方法返回值的映射

建立Data Repository

出於簡便考慮,咱們將直接在代碼裏初始化相關數據,代碼以下:
建立StudentRepository.java,加上@Repository註解,添加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);
    }
}

添加SOAP Webservice 配置

添加一個帶@Configuration註解的配置類:

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("http://www.howtodoinjava.com/xml/school");
        wsdl11Definition.setSchema(countriesSchema);
        return wsdl11Definition;
    }
 
    @Bean
    public XsdSchema countriesSchema()
    {
        return new SimpleXsdSchema(new ClassPathResource("school.xsd"));
    }
}
  • 該類繼承了WsConfigurerAdapter類配置了註解驅動的 Spring-WS編程模式;
  • MessageDispatcherServlet - Spring-WS使用該類處理SOAP 請求,咱們須要把該Servlet注入ApplicationContext ,以便Spring-WS能找到其它Bean;
  • DefaultWsdl11Definition使用XsdSchema暴露了一個標準的的WSDL 1.1,bean的名字studentDetailsWsdl 將會做爲wsdl 暴露出去的名稱,咱們能夠經過http://localhost:8080/service/studentDetailsWsdl.wsdl路徑訪問;

Spring boot SOAP webservice例子演示

使用mvn clean install maven命名構建工程,並使用java -jar target\spring-boot-soap-service-0.0.1-SNAPSHOT.jar命令啓動應用;

執行完以上操做後,將會以默認的8080端口啓動一個tomcat服務,本應用將部署在該服務裏;

如今咱們能夠訪問http://localhost:8080/service/studentDetailsWsdl.wsdl路徑,確認wsdl是不是正確的:
file

若是咱們的wsdl沒問題的話,咱們可使用該WSDL 在SOAP ui 裏建立一個工程,並測試該應用,請求和響應示例以下:
請求:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sch="http://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="http://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>

file

總結

本文學習瞭如何使用Spring Boot建立SOAP webservice,同時也學習瞭如何利用wsdl生成代碼,以及Spring-WS如何處理SOAP 請求

相關文章
相關標籤/搜索