Spring Boot이 포함된 SOAP 마이크로서비스, 2부에서는 Spring Webservices(Spring ws) 사용

Spring Boot을 사용하여 SOAP 마이크로서비스 자습서를 작성하는 두 번째 섹션입니다.이러한 상황에서 우리는 이전 문장과 같은 공작물, 프로젝트 구조, 컨트롤러, WSDL/XSD 파일을 사용할 것이다.
동일한 WSDL과 구성 요소를 사용하면 Apache CXF와 Spring WS가 SOAP 웹 서비스를 만드는 데 있어 중요한 차이점을 이해할 수 있습니다. 이 차이점은 다른 출판물에서 논의됩니다.

If you want to skip the introduction and go directly to the code, then you can find it in my GitHub repository ws-employee-soapspringws


회사 명 / 직원 soapspringws


Spring 부트 및 Spring Web 서비스가 포함된 SOAP 마이크로서비스(Spring WS)


Spring 부트 및 Spring 웹 서비스가 포함된 SOAP 마이크로서비스(Spring ws)


Spring Boot에서 만든 docker 용기를 사용하여 남겨진 클라이언트에 SOAP 노드를 공개합니다
POC의 기술 스택은 다음과 같습니다.
  • 스프링 먼지 방지 커버 2.3.4
  • 자바 15
  • Spring Webservices(Spring ws)
  • 안심 4.3
  • Docker
  • 소프트웨어 요구 사항


    워크스테이션은 다음 도구를 올바르게 구성해야 합니다.
  • Java 15 JDK-https://jdk.java.net/15/
  • Maven-https://maven.apache.org/download.cgi
  • 옵션 도구
  • Docker-https://www.docker.com/products/docker-desktop
  • 토큰에 액세스할 수 있는 Docker hub 계정
  • WSDL 및 도메인 모델


    예제에서는 허구의 직원 SOAP 서비스에서 다음 두 가지 작업을 사용합니다.
  • GetEmployeeById
  • GetEmployeeByName
  • 프레젠테이션에서 XSD와 WSDL을 분리합니다.실제 장면에서는 이 모드가 가장 많이 사용되지만 다른 폴더에는 여러 개의 XSD가 있을 수 있습니다.employee.xsd 서비스의 완전한 도메인 모델을 가지고 다음 그림은 클라이언트에게 보내는 주요 응답을 나타낸다

    View on GitHub
    우리가 첫 번째 부분에서 논의한 바와 같이, 우리는 계약을 우선시하는 방법을 따른다. 이것은 우리가 이전에 정의한 WSDL/XSD가 있다는 것을 의미하고, 우리는spring ws로 그것을 실현하기를 희망한다.끝점이 생성되면 프레임은 동적 WSDL을 생성할 수 있지만, 원본 WSDL을 보존하기를 원하기 때문에 그러기를 원하지 않습니다.따라서 우리는 원시 WSDL을 정적 WSDL로 공개할 것이다.WSDL 및 XSD 모드에 대한 전체 설명

    항목 설정


    이 항목은 maven을 사용합니다. pom.xml의 속성과 의존성은 다음과 같습니다.
    <properties>
        <!-- Override BOM property in Spring Boot for Rest Assured and Groovy-->
        <!-- With rest-assured 4.3.X upgrade the Groovy from 2.5.7 to 3.0.2 -->
        <rest-assured.version>4.3.1</rest-assured.version>
        <groovy.version>3.0.2</groovy.version>
    
        <!-- Other properties-->
        <java.version>15</java.version>
        <springboot.version>2.3.4.RELEASE</springboot.version>
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web-services</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>2.3.3</version>
        </dependency>
    
        <!-- Testing -->
        <dependency>
            <groupId>io.rest-assured</groupId>
            <artifactId>rest-assured</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    

    XSD에서 Java 클래스 생성


    spring ws에서 자바 클래스는 XSD 파일에서만 생성됩니다.WSDL은 Java 생성에 사용되지 않습니다.employee.xsd 이 목적에 사용됩니다.
    우리는 마븐 플러그인을 사용할 것입니다. jaxb2-maven-plugin 자바를 생성하고 클래스는 다음 디렉터리에 저장합니다.
    <source-code>/target/generated-sources/jaxb
    
    다음은 pom.xml 플러그인 구성
    <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>jaxb2-maven-plugin</artifactId>
        <version>2.5.0</version>
        <executions>
            <execution>
                <id>xjc</id>
                <goals>
                    <goal>xjc</goal>
                </goals>
            </execution>
        </executions>
        <configuration>
            <sources>
                <source>${project.basedir}/src/main/resources/wsdl/employee.xsd</source>
            </sources>
        </configuration>
    </plugin>
    
    프로젝트 루트 디렉터리의 명령 창에서 실행하여 자바 클래스를 생성합니다.
    mvn compile
    
    다음 그림은 생성된 클래스를 보여 줍니다.

    Spring Webservices 구성(Spring ws)


    구성 클래스에 주석 @EnableWs 추가
    @Configuration
    @EnableWs
    public class ApplicationConfiguration {
    
    웹 서비스 공개 경로 설정하기;우리의 예에서 그것은 /soap/service/.
    @Bean
    public ServletRegistrationBean<MessageDispatcherServlet> messageDispatcherServlet(ApplicationContext applicationContext) {
        MessageDispatcherServlet servlet = new MessageDispatcherServlet();
        servlet.setApplicationContext(applicationContext);
        servlet.setTransformWsdlLocations(true);
        return new ServletRegistrationBean<>(servlet, "/soap/service/*");
    }
    
    정적 WSDL 및 XSD 공개우리는 서비스 노드를 다음과 같이 구성합니다: /soap/service/EmployeeService.서비스에서 WSDL을 받으려면 http://localhost:8081/soap/service/EmployeeService.wsdl 을 사용합니다.
    @Bean(name = "EmployeeService")
    public Wsdl11Definition defaultWsdl11Definition() {
        SimpleWsdl11Definition wsdl11Definition = new SimpleWsdl11Definition();
        wsdl11Definition.setWsdl(new ClassPathResource("/wsdl/EmployeeServices.wsdl"));
        return wsdl11Definition;
    }
    
    @Bean
    public XsdSchema employee() {
        return new SimpleXsdSchema(new ClassPathResource("/wsdl/employee.xsd"));
    }
    
    WSDL에는 가져온 XSD가 있으므로 XsdSchema 정의가 필요합니다.bean의 이름은 XSD 파일의 이름이어야 합니다.
    중요했어

    If you have more than one XSD, then all of them must be described with XsdShema. Another approach is using the class org.springframework.xml.xsd.commons.CommonsXsdSchemaCollection. If for any reason the XSD files were placed in a relative path in a parent location, then you should consider serving them as static resources, and placing them inside /static directory in your classpath.


    <wsdl:types>
      <xsd:schema>
        <xsd:import namespace="http://www.jpworks.com/employee"
             schemaLocation="../employee.xsd"/>
        </xsd:schema>
    </wsdl:types>
    

    구현 서비스


    WSDL 파일의 portType 부분을 수동으로 구현해야 합니다.

    각 작업은 @PayloadRoot@ResponsePayload 주석을 사용하여 수행됩니다.@PayloadRoot에는 두 개의 원소, 명칭 공간과 부분적인 부분이 있다.작업 GetEmployeeById 의 경우 로컬 섹션 EmployeeByIdRequest 은 다음 섹션에서 가져옵니다.
    <wsdl:operation name="GetEmployeeById">
      <wsdl:input message="tns:EmployeeByIdRequest"/>
    
    이름 공간 값은 참조tns:를 참조하여 WSDL 정의 섹션에서 찾을 수 있습니다.
    <wsdl:definitions 
       xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
       xmlns:tns="http://www.jpworks.com/employee"
    
    java 방법은 XSD로 생성된 클래스를 사용하여 직접 작업을 수행하는 것입니다.
    @PayloadRoot(namespace = NAMESPACE_URI, localPart = "EmployeeByIdRequest")
    @ResponsePayload
    public EmployeeResponse getEmployeeById(@RequestPayload EmployeeByIdRequest parameters) {
    
    가짜 백엔드 서비스의 완전한 구현은 다음과 같다.
    package com.jpworks.datajdbc.service;
    
    import lombok.RequiredArgsConstructor;
    import lombok.extern.slf4j.Slf4j;
    import com.jpworks.employee.*;
    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;
    
    @Slf4j
    @Endpoint
    @RequiredArgsConstructor
    public class EmployeeEndpoint{
    
        private final BackendService backendService;
        private static final String NAMESPACE_URI = "http://www.jpworks.com/employee";
    
        @PayloadRoot(namespace = NAMESPACE_URI, localPart = "EmployeeByIdRequest")
        @ResponsePayload
        public EmployeeResponse getEmployeeById(@RequestPayload EmployeeByIdRequest parameters) {
            EmployeeResponse employeeResponse = new EmployeeResponse();
            try{
                employeeResponse.setEmployee(backendService.getEmployeeById(parameters.getId()));
            }
            catch (Exception e){
                log.error("Error while setting values for employee object", e);
            }
            return employeeResponse;
        }
    
        @PayloadRoot(namespace = NAMESPACE_URI, localPart = "EmployeeByNameRequest")
        @ResponsePayload
        public EmployeesResponse getEmployeesByName(@RequestPayload EmployeeByNameRequest parameters) {
            EmployeesResponse employeesResponse = new EmployeesResponse();
            try{
                employeesResponse.getEmployee().addAll(backendService.getEmployeesByName(parameters.getFirstname(), parameters.getLastname()));
            }
            catch (Exception e){
                log.error("Error while setting values for employee object", e);
            }
            return employeesResponse;
        }
    }
    

    응용 프로그램 실행


    명령 창에서 루트 항목에서 실행:
    mvn spring-boot:run
    
    콘솔의 로그:
    
      .   ____          _            __ _ _
     /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
    ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
     \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
      '  |____| .__|_| |_|_| |_\__, | / / / /
     =========|_|==============|___/=/_/_/_/
     :: Spring Boot ::        (v2.3.4.RELEASE)
    
    2020-10-13 15:03:35.154  INFO 157100 --- [           main] com.jpworks.datajdbc.MainApplication     : Starting MainApplication on LNAR-PC0NTFTQ with PID 157100 (C:\workspace\dev\datajdbc\ws-employee-soapspringws\target\classes started by jponte in C:\workspace\dev\datajdbc\ws-employee-soapspringws)
    2020-10-13 15:03:35.156 DEBUG 157100 --- [           main] com.jpworks.datajdbc.MainApplication     : Running with Spring Boot v2.3.4.RELEASE, Spring v5.2.9.RELEASE
    2020-10-13 15:03:35.157  INFO 157100 --- [           main] com.jpworks.datajdbc.MainApplication     : The following profiles are active: local
    2020-10-13 15:03:35.642  INFO 157100 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.ws.config.annotation.DelegatingWsConfiguration' of type [org.springframework.ws.config.annotation.DelegatingWsConfiguration$$EnhancerBySpringCGLIB$$1d99be26] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
    2020-10-13 15:03:35.689  INFO 157100 --- [           main] .w.s.a.s.AnnotationActionEndpointMapping : Supporting [WS-Addressing August 2004, WS-Addressing 1.0]
    2020-10-13 15:03:35.988  INFO 157100 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8081 (http)
    2020-10-13 15:03:35.997  INFO 157100 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
    2020-10-13 15:03:35.998  INFO 157100 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.38]
    2020-10-13 15:03:36.097  INFO 157100 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
    2020-10-13 15:03:36.097  INFO 157100 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 902 ms
    2020-10-13 15:03:36.268  INFO 157100 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
    2020-10-13 15:03:36.405  INFO 157100 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8081 (http) with context path ''
    2020-10-13 15:03:36.414  INFO 157100 --- [           main] com.jpworks.datajdbc.MainApplication     : Started MainApplication in 1.627 seconds (JVM running for 2.19)
    
    서비스의 wsdl을 가져오려면 브라우저에 다음과 같이 쓰십시오.
    http://localhost:8081/soap/service/EmployeeService.wsdl
    

    SoapUI 및 엔드포인트 테스트 어플리케이션 사용:http://localhost:8081/soap/service/EmployeeService

    결론


    이 강좌는 Spring Boot 및 Spring Webservices(Spring ws)를 사용하여 계약 우선순위로 SOAP 마이크로서비스를 만드는 방법을 설명합니다.
    질문이 있으시면 언제든지 댓글로 질문해 주십시오.읽어주셔서 감사합니다!

    좋은 웹페이지 즐겨찾기