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 에서 사용할 수 있습니다 .