Springを使用したSOAP Webサービスの作成

1. 概要

このチュートリアルでは、Spring Boot Starter Webサービスを使用して* SOAPベースのWebサービス*を作成する方法を説明します。

2. SOAP Webサービス

Webサービスは、要するに、ネットワークを介した通信を可能にする、マシンツーマシンのプラットフォームに依存しないサービスです。
SOAPはメッセージングプロトコルです。 メッセージ(リクエストとレスポンス)は、HTTPを介した* XMLドキュメントです。 * XMLコントラクトはWSDL *(Webサービス記述言語)で定義されています。 メッセージ、バインディング、操作、およびサービスの場所を定義する一連のルールを提供します。
SOAPで使用されるXMLは非常に複雑になる可能性があります。 このため、このチュートリアルで説明するように、link:/jax-ws[JAX-WS]やSpringなどのフレームワークでSOAPを使用するのが最適です。

3. コントラクトファースト開発スタイル

Webサービスを作成する場合、次の2つのアプローチがあります:およびhttps://docs.spring.io/spring-ws/sites/1.5/reference/html/why-contract-first.html []。 コントラクトラストアプローチを使用する場合、Javaコードから始め、クラスからWebサービスコントラクト(WSDL)を生成します。 コントラクトファーストを使用する場合、* WSDLコントラクトから開始し、そこからJavaクラスを生成します*
Spring-WSは、コントラクトファースト開発スタイルのみをサポートします。

4. Spring Bootプロジェクトのセットアップ

SOAP WSサーバーを定義するlink:/spring-boot[Spring Boot]プロジェクトを作成します。

4.1. Mavenの依存関係

https://search.maven.org/search?q=g:org.springframework.boot%20a:spring-boot-starter-parent[_spring-boot-starter-parent_]をプロジェクトに追加することから始めましょう。
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.2.RELEASE</version>
</parent>
次に、https://search.maven.org/search?q=g:org.springframework.boot%20a:spring-boot-starter-web-services[_spring-boot-starter-web-services_]を追加してみましょう。 _https://search.maven.org/search?q = g:wsdl4j%20%20a:wsdl4j [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_ Webサービスリクエストの形式があります*。 タイプ_string_の1つのパラメーターを受け入れるように定義します。
次に、_country_型のオブジェクトを含む応答の形式を定義します。
最後に、_country_オブジェクト内で使用される_currency_オブジェクトが表示されます。

4.3. ドメインJavaクラスを生成する

ここで、前のセクションで定義したXSDファイルからJavaクラスを生成します。 https://search.maven.org/search?q=g:org.codehaus.mojo%20a:jaxb2-maven-plugin[_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>
ここで、2つの重要な構成に注目してください。
  • _ <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 Webサービスエンドポイントを追加する

SOAP Webサービスエンドポイントクラスは、サービスに対するすべての着信要求を処理します。 処理を開始し、応答を送り返します。
これを定義する前に、Webサービスにデータを提供するために_Country_リポジトリを作成します。
@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にWebサービスとしてクラスを登録します
    終点

  • _ @ PayloadRoot_ – に従ってハンドラーメソッドを定義します
    _namespace_および_localPart_属性

  • _ @ ResponsePayload_ –このメソッドが値を返すことを示します
    応答ペイロードにマッピングされます

  • _ @ RequestPayload_ –このメソッドがパラメーターを受け入れることを示します
    着信リクエストからマッピングされる

4.5. SOAP Webサービス構成Bean

次に、リクエストを受信するようにSpringメッセージディスパッチャサーブレットを構成するためのクラスを作成しましょう。
@EnableWs
@Configuration
public class WebServiceConfig extends WsConfigurerAdapter {
    // bean definitions
}
_ @ EnableWs_は、このSpring BootアプリケーションでSOAP Webサービス機能を有効にします。 _WebServiceConfig_クラスは、注釈駆動のSpring-WSプログラミングモデルを構成する_WsConfigurerAdapter_ baseクラスを拡張します。
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 Beanを見つけられるように、_servlet_の_ApplicationContext_オブジェクトを設定します。
また、WSDLロケーションサーブレット変換も有効にします。 これにより、WSDLの_soap:address_の場所属性が変換され、着信要求のURLが反映されます。
最後に、_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
アプリケーションが正常に実行されているかどうかを確認するには、http:// localhost:8080 / ws / countries.wsdlのURLから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 Webサービスを作成する方法を学びました。 また、XSDファイルからJavaコードを生成する方法を学び、SOAP要求の処理に必要なSpring Beanを構成する方法を見ました。
完全なソースコードは、https://github.com/eugenp/tutorials/tree/master/spring-soap [GitHub]で入手できます。