1. 概要

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

2. SOAPWebサービス

要するに、Webサービスは、ネットワークを介した通信を可能にする、マシン間でプラットフォームに依存しないサービスです。

SOAPはメッセージングプロトコルです。 メッセージ(要求と応答)は、HTTPを介したXMLドキュメントです。  XMLコントラクトは、WSDL (Webサービス記述言語)によって定義されます。 これは、サービスのメッセージ、バインディング、操作、および場所を定義するための一連のルールを提供します。

SOAPで使用されるXMLは非常に複雑になる可能性があります。 このため、このチュートリアルで説明するように、JAX-WSやSpringなどのフレームワークでSOAPを使用するのが最適です。

3. 契約優先の開発スタイル

Webサービスを作成する場合、Contract-LastContract-Firstの2つのアプローチが考えられます。 コントラクトラストアプローチを使用する場合、Javaコードから開始し、Webサービスコントラクトを生成します(WSDL)クラスから。 コントラクトファーストを使用する場合、はWSDLコントラクトから開始し、そこからJavaクラスを生成します。

Spring-WSは、コントラクトファーストの開発スタイルのみをサポートします。

4. SpringBootプロジェクトの設定

Spring Boot プロジェクトを作成し、SOAPWSサーバーを定義します。

4.1. Mavenの依存関係

プロジェクトにspring-boot-starter-parentを追加することから始めましょう。

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.6.1</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>

このファイルには、getCountryRequestWebサービスリクエストの形式が表示されます。 タイプstringの1つのパラメーターを受け入れるように定義します。

次に、countryタイプのオブジェクトを含む応答の形式を定義します。

最後に、countryオブジェクト内で使用されるcurrencyオブジェクトが表示されます。

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>

ここで、2つの重要な構成に注目します。

  • $ {project.basedir} / src / main / resources –XSDファイルの場所
  • $ {project.basedir} /src/main/java –Javaコードを生成する場所

Javaクラスを生成するには、Javaインストールからxjcツールを使用するだけです。 私たちのMavenプロジェクトでは、物事はさらに単純ですが、クラスは通常のMavenビルド中に自動的に生成されます

mvn compile

4.4. SOAPWebサービスエンドポイントを追加します

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 –クラスをWebサービスエンドポイントとしてSpringWSに登録します
  • @PayloadRoot 名前空間とlocalPart属性に従ってハンドラーメソッドを定義します
  • @ResponsePayload –このメソッドが応答ペイロードにマップされる値を返すことを示します
  • @RequestPayload –このメソッドが着信リクエストからマップされるパラメーターを受け入れることを示します

4.5. SOAPWebサービス構成Bean

次に、リクエストを受信するようにSpringメッセージディスパッチャーサーブレットを構成するためのクラスを作成しましょう。

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

@EnableWs は、このSpringBootアプリケーションでSOAPWebサービス機能を有効にします。 WebServiceConfig クラスは、 WsConfigurerAdapter 基本クラスを拡張します。これは、アノテーション駆動型のSpring-WSプログラミングモデルを構成します。

SOAPリクエストの処理に使用されるMessageDispatcherServletを作成しましょう。

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

サーブレットの挿入されたApplicationContextオブジェクトを設定して、Spring-WSが他のSpringBeanを見つけられるようにします。

また、WSDLロケーションサーブレット変換を有効にします。 これにより、WSDLの soap:address のロケーション属性が変換され、着信リクエストのURLが反映されます。

最後に、DefaultWsdl11Definitionオブジェクトを作成しましょう。 これにより、XsdSchemaを使用して標準のWSDL1.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 / countrys.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やGoogleChrome拡張機能Wizdlerなどの外部ツールを使用できます。 もう1つの方法は、シェルで次のコマンドを実行することです。

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. 結論

この記事では、SpringBootを使用してSOAPWebサービスを作成する方法を学びました。 また、XSDファイルからJavaコードを生成する方法を学び、SOAP要求を処理するために必要なSpringBeanを構成する方法を学びました。

完全なソースコードは、GitHubで入手できます。