Menu Close

40.3. スタブコードの生成

概要

呼び出しの非同期スタイルでは、SEI で定義された専用の非同期メソッド用に追加のスタブコードが必要です。この特別なスタブコードはデフォルトで生成されません。非同期機能に切り替え、必要なスタブコードを生成するには、WSDL 2.0 仕様からのマッピングカスタマイズ機能を使用する必要があります。

カスタマイズにより、Maven コード生成プラグインがスタブコードを生成する方法を変更することができます。特に、WSDL から Java へのマッピングを変更し、特定の機能を有効にすることができます。ここでは、非同期呼び出し機能の有効化にカスタマイズが使用されます。カスタマイズは、jaxws:bindings タグを使用して定義するバインディング宣言を使用して指定します。ここでは、jaxws プレフィックスは http://java.sun.com/xml/ns/jaxws namespace に関連付けられます。バインディング宣言を指定する方法は 2 つあります。

外部バインディング宣言
外部バインディング宣言を使用する場合、jaxws:bindings 要素は WSDL コントラクトとは別のファイルで定義されます。スタブコードを生成するときに、バインディング宣言ファイルの場所をコードジェネレーターに指定します。
組み込みバインディング宣言
組み込みバインディング宣言を使用する場合は、jaxws:bindings 要素を直接 WSDL コントラクトに組み込み、それを WSDL 拡張として扱います。この場合、jaxws:bindings の設定は直接の親要素にのみ適用されます。

外部バインディング宣言の使用

非同期呼び出しを有効にするバインディング宣言ファイルのテンプレートは、例40.2「非同期バインディング宣言のテンプレート」に示されます。

例40.2 非同期バインディング宣言のテンプレート

<bindings xmlns:xsd="http://www.w3.org/2001/XMLSchema"
          xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
          wsdlLocation="AffectedWSDL"
          xmlns="http://java.sun.com/xml/ns/jaxws">
  <bindings node="AffectedNode">
    <enableAsyncMapping>true</enableAsyncMapping>
  </bindings>
</bindings>

ここで、AffectedWSDL は、このバインディング宣言の影響を受ける WSDL コントラクトの URL を指定します。AffectedNode は、このバインディング宣言の影響を受ける WSDL コントラクトからのノードを指定する XPath の値です。WSDL コントラクト全体が影響を受けるようにするには、AffectedNodewsdl:definitions に設定できます。非同期呼び出し機能を有効にするには、jaxws:enableAsyncMapping 要素を true に設定します。

たとえば、GreeterAsync インターフェースに対してのみ非同期メソッドを生成する場合は、前述のバインディング宣言で <bindings node="wsdl:definitions/wsdl:portType[@name='GreeterAsync']"> を指定することができます。

バインディング宣言がファイル async_binding.xml に保存されている場合、例40.3「コンシューマーコードの生成」に記載されているように POM を設定します。

例40.3 コンシューマーコードの生成

<plugin>
  <groupId>org.apache.cxf</groupId>
  <artifactId>cxf-codegen-plugin</artifactId>
  <version>${cxf.version}</version>
  <executions>
    <execution>
      <id>generate-sources</id>
      <phase>generate-sources</phase>
      <configuration>
        <sourceRoot>outputDir</sourceRoot>
        <wsdlOptions>
          <wsdlOption>
            <wsdl>hello_world.wsdl</wsdl>
            <extraargs>
              <extraarg>-client</extraarg>
              <extraarg>-b async_binding.xml</extraarg>
            </extraargs>
          </wsdlOption>
        </wsdlOptions>
      </configuration>
      <goals>
        <goal>wsdl2java</goal>
      </goals>
    </execution>
  </executions>
</plugin>

-b オプションは、コードジェネレーターに対し、外部バインディングファイルの場所を指定します。

コードジェネレーターの詳細は、「cxf-codegen-plugin」を参照してください。

組み込みバインディング宣言の使用

また、jaxws:bindings 要素とその関連の jaxws:enableAsynchMapping 子要素を直接 WSDL に配置して、バインディングのカスタマイズをサービスを定義する WSDL ドキュメントに直接組み込むこともできます。また、jaxws プレフィックスの namespace 宣言を追加する必要もあります。

例40.4「非同期マッピングのバインディング宣言が組み込まれた WSDL」に、操作の非同期マッピングをアクティベートするバインディング宣言が組み込まれた WSDL ファイルを示します。

例40.4 非同期マッピングのバインディング宣言が組み込まれた WSDL

<wsdl:definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
                  ...
                  xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
                  ...>
  ...
  <wsdl:portType name="GreeterAsync">
    <wsdl:operation name="greetMeSometime">
      <jaxws:bindings> <jaxws:enableAsyncMapping>true</jaxws:enableAsyncMapping> </jaxws:bindings>
      <wsdl:input name="greetMeSometimeRequest"
                  message="tns:greetMeSometimeRequest"/>
      <wsdl:output name="greetMeSometimeResponse"
                   message="tns:greetMeSometimeResponse"/>
    </wsdl:operation>
  </wsdl:portType>
  ...
</wsdl:definitions>

バインディング宣言を WSDL ドキュメントに組み込む場合、宣言を配置する場所を変えることで宣言の影響を受けるスコープを制御できます。宣言が wsdl:definitions 要素の子として配置されると、コードジェネレーターは、WSDL ドキュメントに定義されたすべての操作に非同期メソッドを作成します。wsdl:portType 要素の子として配置されると、コードジェネレーターは、インターフェースに定義されたすべての操作に非同期メソッドを作成します。wsdl:operation 要素の子として配置されると、コードジェネレーターは、その操作にのみ非同期メソッドを作成します。

組み込み宣言を使用する際に、特別なオプションをコードジェネレーターに渡す必要はありません。コードジェネレーターはそれを認識し、適切に機能します。

生成されるインターフェース

この方法でスタブコードを生成した後、GreeterAsync SEI (ファイル GreeterAsync.java 内) は 例40.5「非同期呼び出しのメソッドを含むサービスエンドポイントインターフェース」に示すように定義されます。

例40.5 非同期呼び出しのメソッドを含むサービスエンドポイントインターフェース

package org.apache.hello_world_async_soap_http;

import org.apache.hello_world_async_soap_http.types.GreetMeSometimeResponse;
...

public interface GreeterAsync
{
  public Future<?> greetMeSometimeAsync(
        java.lang.String requestType,
        AsyncHandler<GreetMeSometimeResponse> asyncHandler
    );

    public Response<GreetMeSometimeResponse> greetMeSometimeAsync(
        java.lang.String requestType
    );

    public java.lang.String greetMeSometime(
        java.lang.String requestType
    );
}

通常の同期メソッド greetMeSometime() のほかに、greetMeSometime 操作用に 2 つの非同期メソッドも生成されます。

  • コールバックのアプローチ: publicFuture<?>greetMeSomtimeAsyncjava.lang.StringrequestTypeAsyncHandler<GreetMeSomtimeResponse>asyncHandler
  • ポーリングのアプローチ: publicResponse<GreetMeSomeTimeResponse>greetMeSometimeAsyncjava.lang.StringrequestType