1. 개요

이 사용방법(예제)에서는 Spring Boot Starter 웹 서비스 를 사용하여 SOAP 기반 웹 서비스 를 만드는 방법을 배웁니다 .

2. SOAP 웹 서비스

즉, 웹 서비스는 네트워크를 통한 통신을 허용하는 기계 VS 기계, 플랫폼 독립적인 서비스입니다.

SOAP는 메시징 프로토콜입니다. 메시지(요청 및 응답)는 HTTP를 통한 XML 문서 입니다. XML 계약은 WSDL (Web Services Description Language)로 정의됩니다. 서비스의 메시지, 바인딩, 작업 및 위치를 정의하는 규칙 집합을 제공합니다.

SOAP에서 사용되는 XML은 매우 복잡해질 수 있습니다. 이러한 이유로 이 예제에서 볼 수 있듯이 JAX-WS 또는 Spring과 같은 프레임워크와 함께 SOAP를 사용하는 것이 가장 좋습니다.

3. 계약 우선 개발 스타일

웹 서비스를 생성할 때 두 가지 접근 방식이 있습니다:  Contract-Last  및  Contract-First . 마지막 계약 방식을 사용하는 경우 Java 코드로 시작 하여 클래스에서 웹 서비스 계약( WSDL )을 생성합니다. 계약 우선을 사용할 때 Java 클래스를 생성하는 WSDL 계약부터 시작합니다.

Spring-WS는 계약 우선 개발 스타일만 지원합니다.

4. 스프링 부트 프로젝트 설정

SOAP WS 서버를 정의할 Spring Boot 프로젝트를 생성 합니다.

4.1. 메이븐 의존성

프로젝트 에 spring-boot-starter-parent 를 추가하여 시작하겠습니다 .

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.2</version>
</parent>

다음으로  spring-boot-starter-web-services 및  wsdl4j 의존성을 추가해 보겠습니다.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<dependency>
    <groupId>wsdl4j</groupId>
    <artifactId>wsdl4j</artifactId>
</dependency>

4.2. XSD 파일

계약 우선 접근 방식에서는 먼저 서비스에 대한 도메인(메서드 및 매개 변수)을 생성해야 합니다. Spring-WS가 자동으로 WSDL로 내보낼 XML 스키마 파일(XSD)을 사용합니다.

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.baeldung.com/springsoap/gen"
           targetNamespace="http://www.baeldung.com/springsoap/gen" elementFormDefault="qualified">

    <xs:element name="getCountryRequest">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="name" type="xs:string"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="getCountryResponse">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="country" type="tns:country"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:complexType name="country">
        <xs:sequence>
            <xs:element name="name" type="xs:string"/>
            <xs:element name="population" type="xs:int"/>
            <xs:element name="capital" type="xs:string"/>
            <xs:element name="currency" type="tns:currency"/>
        </xs:sequence>
    </xs:complexType>

    <xs:simpleType name="currency">
        <xs:restriction base="xs:string">
            <xs:enumeration value="GBP"/>
            <xs:enumeration value="EUR"/>
            <xs:enumeration value="PLN"/>
        </xs:restriction>
    </xs:simpleType>
</xs:schema>

이 파일에서 getCountryRequest 웹 서비스 요청 의 형식을 볼 수 있습니다 . string 유형의 매개변수 하나를 허용하도록 정의합니다 .

다음으로 국가 유형의 개체를 포함하는 응답 형식을 정의합니다 .

마지막으로 국가 개체 내에서 사용되는 통화 개체 를 볼 수 있습니다 .

4.3. 도메인 Java 클래스 생성

이제 이전 섹션에서 정의한 XSD 파일에서 Java 클래스를 생성합니다. jaxb2 -maven-plugin 은 빌드 시간 동안 이 작업을 자동으로 수행합니다. 플러그인은 XJC 도구를 코드 생성 엔진으로 사용합니다. XJC는 XSD 스키마 파일을 완전히 어노테이션이 달린 Java 클래스로 컴파일합니다.

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>

여기서 우리는 두 가지 중요한 구성을 알 수 있습니다.

  • <schemaDirectory>${project.basedir}/src/main/resources</schemaDirectory> – XSD 파일의 위치
  • <outputDirectory>${project.basedir}/src/main/java</outputDirectory> – Java 코드를 생성할 위치

Java 클래스를 생성하기 위해 Java 설치에서 XJC 도구를 사용할 수 있습니다. 일반적인 Maven 빌드 중에 클래스가 자동으로 생성되므로 Maven 프로젝트에서는 훨씬 더 간단합니다 .

mvn compile

4.4. SOAP 웹 서비스 Endpoints 추가

SOAP 웹 서비스 Endpoints 클래스는 서비스에 대한 모든 수신 요청을 처리합니다. 처리를 시작하고 응답을 다시 보냅니다.

이를 정의하기 전에 웹 서비스에 데이터를 제공하기 위해 국가 리포지토리를 만듭니다.

@Component
public class CountryRepository {

    private static final Map<String, Country> countries = new HashMap<>();

    @PostConstruct
    public void initData() {
        // initialize countries map
    }

    public Country findCountry(String name) {
        return countries.get(name);
    }
}

다음으로 엔드포인트를 구성합니다.

@Endpoint
public class CountryEndpoint {

    private static final String NAMESPACE_URI = "http://www.baeldung.com/springsoap/gen";

    private CountryRepository countryRepository;

    @Autowired
    public CountryEndpoint(CountryRepository countryRepository) {
        this.countryRepository = countryRepository;
    }

    @PayloadRoot(namespace = NAMESPACE_URI, localPart = "getCountryRequest")
    @ResponsePayload
    public GetCountryResponse getCountry(@RequestPayload GetCountryRequest request) {
        GetCountryResponse response = new GetCountryResponse();
        response.setCountry(countryRepository.findCountry(request.getName()));

        return response;
    }
}

주의해야 할 몇 가지 세부 사항은 다음과 같습니다.

  • @Endpoint – 클래스를 Spring WS에 웹 서비스 엔드포인트로 등록합니다.
  • @PayloadRoot네임스페이스localPart 속성 에 따라 핸들러 메서드를 정의합니다. 
  • @ResponsePayload – 이 메서드가 응답 페이로드에 매핑할 값을 반환함을 나타냅니다.
  • @RequestPayload – 이 메서드가 들어오는 요청에서 매핑할 매개변수를 수락함을 나타냅니다.

4.5. SOAP 웹 서비스 구성 Bean

이제 요청을 수신하도록 Spring 메시지 디스패처 서블릿을 구성하기 위한 클래스를 생성해 보겠습니다.

@EnableWs
@Configuration
public class WebServiceConfig extends WsConfigurerAdapter {
    // bean definitions
}

@EnableWs 는 이 Spring Boot 애플리케이션에서 SOAP 웹 서비스 기능을 활성화합니다. WebServiceConfig 클래스는 어노테이션 기반 Spring-WS 프로그래밍 모델을 구성하는 WsConfigurerAdapter   기본 클래스를 확장 합니다.

SOAP 요청을 처리하는 데 사용되는 MessageDispatcherServlet을 생성해 보겠습니다  .

@Bean
public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
    MessageDispatcherServlet servlet = new MessageDispatcherServlet();
    servlet.setApplicationContext(applicationContext);
    servlet.setTransformWsdlLocations(true);
    return new ServletRegistrationBean(servlet, "/ws/*");
}

 Spring-WS가 다른 Spring 빈을 찾을 수 있도록 서블릿 의 주입된 ApplicationContext 개체를 설정합니다.

또한 WSDL 위치 서블릿 변환을 활성화합니다. 이는 들어오는 요청의 URL을 반영하도록 WSDL에서 soap:address 의 위치 특성을 변환합니다 .

마지막으로 DefaultWsdl11Definition 개체를 만듭니다. 이는 XsdSchema를 사용하여 표준 WSDL 1.1을 노출합니다. WSDL 이름은 bean 이름과 동일합니다.

@Bean(name = "countries")
public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema countriesSchema) {
    DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
    wsdl11Definition.setPortTypeName("CountriesPort");
    wsdl11Definition.setLocationUri("/ws");
    wsdl11Definition.setTargetNamespace("http://www.baeldung.com/springsoap/gen");
    wsdl11Definition.setSchema(countriesSchema);
    return wsdl11Definition;
}

@Bean
public XsdSchema countriesSchema() {
    return new SimpleXsdSchema(new ClassPathResource("countries.xsd"));
}

5. SOAP 프로젝트 테스트

프로젝트 구성이 완료되면 테스트할 준비가 된 것입니다.

5.1. 프로젝트 빌드 및 실행

WAR 파일을 만들어 외부 애플리케이션 서버에 배포할 수 있습니다. 대신 애플리케이션을 시작하고 실행하는 더 빠르고 쉬운 방법인 Spring Boot를 사용할 것입니다.

먼저 다음 클래스를 추가하여 애플리케이션을 실행 가능하게 만듭니다.

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

이 응용 프로그램을 만드는 데 XML 파일(예: web.xml)을 사용하지 않는다는 점에 유의하십시오. 모두 순수한 Java입니다.

이제 애플리케이션을 빌드하고 실행할 준비가 되었습니다.

mvn spring-boot:run

애플리케이션이 제대로 실행되고 있는지 확인하기 위해 다음 URL을 통해 WSDL을 열 수 있습니다. http://localhost:8080/ws/countries.wsdl

5.2. SOAP 요청 테스트

요청을 테스트하기 위해 다음 파일을 만들고 이름을 request.xml로 지정합니다.

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                  xmlns:gs="http://www.baeldung.com/springsoap/gen">
    <soapenv:Header/>
    <soapenv:Body>
        <gs:getCountryRequest>
            <gs:name>Spain</gs:name>
        </gs:getCountryRequest>
    </soapenv:Body>
</soapenv:Envelope>

테스트 서버에 요청을 보내기 위해 SoapUI 또는 Google Chrome 확장 프로그램 Wizdler와 같은 외부 도구를 사용할 수 있습니다. 또 다른 방법은 쉘에서 다음 명령을 실행하는 것입니다.

curl --header "content-type: text/xml" -d @request.xml http://localhost:8080/ws

결과 응답은 들여쓰기나 줄 바꿈 없이 읽기 쉽지 않을 수 있습니다.

포맷된 것을 보기 위해 복사하여 IDE나 다른 도구에 붙여넣을 수 있습니다. xmllib2를 설치한 경우 curl 명령의 출력을 xmllint 로 파이프할 수 있습니다 .

curl [command-line-options] | xmllint --format -

응답에는 스페인에 대한 정보가 포함되어야 합니다.

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
    <ns2:getCountryResponse xmlns:ns2="http://www.baeldung.com/springsoap/gen">
        <ns2:country>
            <ns2:name>Spain</ns2:name>
            <ns2:population>46704314</ns2:population>
            <ns2:capital>Madrid</ns2:capital>
            <ns2:currency>EUR</ns2:currency>
        </ns2:country>
    </ns2:getCountryResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

6. 결론

이 기사에서는 Spring Boot를 사용하여 SOAP 웹 서비스를 만드는 방법을 배웠습니다. 또한 XSD 파일에서 Java 코드를 생성하는 방법도 시연했습니다. 마지막으로 SOAP 요청을 처리하는 데 필요한 Spring 빈을 구성했습니다.

전체 소스 코드는 GitHub 에서 사용할 수 있습니다 .

Generic footer banner