10.21.1 サービスクラスおよびポートのインジェクション

J2EEサーバ上で動作するWebサービスクライアントの,次に示すフィールドおよびメソッドにjavax.xml.ws.WebServiceRefアノテーションを指定すると,J2EEサーバが,Webサービスクライアントのインスタンス生成時にサービスクラスおよびポートの生成とインジェクションを行います。javax.xml.ws.WebServiceRefアノテーションについては,「19.3 アノテーションのサポート範囲」を参照してください。

javax.xml.ws.WebServiceRefアノテーションによるインジェクションの利用には,次のような利点があります。

Webサービスクライアントのインスタンスの生成については,「10.21.1(2) Webサービスクライアントのインスタンス生成」を参照してください。

注意事項
  • javax.xml.ws.WebServiceRefアノテーションを指定できるのは,WebサービスクライアントをサーブレットまたはEJBとして実装する場合だけです。これ以外のアプリケーションとして実装するときは指定できません。例えば,コマンドラインアプリケーションのWebサービスクライアントで,サービスクラスやポートをインジェクトすることはできません。
  • サービスクラスおよびポートのインスタンスは,J2EEアプリケーションの開始時に一度だけ生成します。生成するインスタンスの数は,javax.xml.ws.WebServiceRefアノテーションを指定したサービスクラスおよびポートごとに一つだけです。
  • サービスクラスおよびポートのインジェクションは,Webサービスクライアントのインスタンスを生成するごとに行います。
  • WebサービスクライアントをEJBとして実装する場合,Stateless Session Beanでのプーリングを有効に設定することで,J2EEアプリケーションの開始時に複数のWebサービスクライアントのインスタンスを生成しておくことができます。この場合,javax.xml.ws.WebServiceRefアノテーションを指定したサービスクラスおよびポートのインスタンスを一つ生成して,それをWebサービスクライアントの各インスタンスにインジェクトします。Webサービスクライアントのインスタンス生成については,「10.21.1(2) Webサービスクライアントのインスタンス生成」を参照してください。
  • WebサービスAからWebサービスBを呼び出す構成で,javax.xml.ws.WebServiceRefアノテーションを指定してWebサービスBのサービスクラスやポートを,WebサービスAにインジェクトすることはできません。
  • Webサービスクライアントが参照するクラスでjavax.xml.ws.WebServiceRefアノテーションは指定できません。
  • javax.xml.ws.WebServiceRefアノテーションによってサービスクラスやポートのインジェクションを行うJ2EEアプリケーションを,リロード機能を使用して入れ替えることはできません。入れ替える場合は,入れ替え前のJ2EEアプリケーションを停止・削除してから,入れ替えるJ2EEアプリケーションをインポート・開始してください。リロード機能の詳細については,マニュアル「アプリケーションサーバ 機能解説 基本・開発編(コンテナ共通機能)」を参照してください。
<この項の構成>
(1) javax.xml.ws.WebServiceRefアノテーションの指定例
(2) Webサービスクライアントのインスタンス生成
(3) ハンドラフレームワークの使用
(4) フィーチャの有効化
(5) 要求コンテキストのプロパティ変更

(1) javax.xml.ws.WebServiceRefアノテーションの指定例

javax.xml.ws.WebServiceRefアノテーションの指定例を次に示します。

(2) Webサービスクライアントのインスタンス生成

J2EEアプリケーションの開始時にWebサービスクライアントのインスタンスを生成するには,次のように設定します。

サーブレットの場合
Webサービスクライアントが含まれるWARファイルのweb.xmlにload-on-startup要素を指定します。なお,load-on-startup要素を指定しないときは,最初のWebアプリケーション実行時にインスタンスを生成します。詳細については,マニュアル「アプリケーションサーバ 機能解説 基本・開発編(Webコンテナ)」を参照してください。
EJBの場合
Stateless Session Beanでのプーリングを有効に設定します。J2EEアプリケーション開始時に,Stateless Session Beanでのプーリングの最小値分だけインスタンス生成を実行します。なお,Stateless Session Beanでのプーリングを使用しないときは,最初のJ2EEアプリケーション実行時にインスタンスを生成します。詳細については,「アプリケーションサーバ 機能解説 基本・開発編(EJBコンテナ)」を参照してください。
注意事項
Webサービスクライアントと接続先のWebサービスが,同じJ2EEサーバ上にデプロイされている環境では,J2EEサーバの起動時にインジェクションに失敗します(KDJW40043-E)。
インジェクションが失敗する場合の対策方法を次に示します。
  • javax.xml.ws.WebServiceRefアノテーションのwsdlLocation要素に,相対パスまたは絶対パスでローカルに格納したWSDL文書を指定してください。
  • J2EEサーバを停止する前に,Webサービスクライアントが含まれるJ2EEアプリケーションを停止してください。J2EEサーバを再起動したあとに,Webサービスクライアントを開始してください。
  • WebサービスとWebサービスクライアントを別のJ2EEサーバにデプロイして,WebサービスをデプロイしたJ2EEサーバを起動したあとにWebサービスクライアントをデプロイしたJ2EEサーバを起動してください。
  • カタログ機能を使用して,サービスクラスまたはポートのインジェクションでローカルに格納したWSDL文書を参照するように設定してください。

(3) ハンドラフレームワークの使用

javax.xml.ws.WebServiceRefアノテーションを指定してインジェクトしたサービスクラスまたはポートでハンドラフレームワークを使用する場合,APIを使用してハンドラチェインを設定します。ハンドラチェインの設定については,「36.9.2 Web サービスクライアント側のハンドラチェインの設定」を参照してください。なお,ハンドラチェインの設定は,ポートに対して一度だけ実行すればいいので,Webサービスクライアントの初期化処理での実行をお勧めします。Webサービスを呼び出すごとに設定する必要はありません。初期化処理を実行するメソッドを次に示します。

Webサービスクライアントをサーブレットとして実装する場合
initメソッドまたはjavax.annotation.PostConstructアノテーションを指定したメソッド
EJBとして実装する場合
javax.annotation.PostConstructアノテーションを指定したメソッド

(4) フィーチャの有効化

ポート型のフィールドや,フィールドに対応するsetterメソッドに,javax.xml.ws.WebServiceRefアノテーションとフィーチャに対応するアノテーションを同時に指定すると,インジェクションを行うポートのフィーチャを有効化できます。ただし,フィーチャに対応するアノテーションを指定したフィールドまたはフィールドに対応するsetterメソッドに,javax.xml.ws.WebServiceRefアノテーションを指定しない場合は,フィーチャは有効になりません。また,サービスクラス型のフィールドやフィールドに対応するsetterメソッドに対しては,フィーチャに対応するアノテーションを指定できません。

フィーチャを有効化するときに,ポートに指定できるアノテーションを次に示します。各アノテーションについては,「16.2 JavaからWSDLへのマッピングのカスタマイズ」を参照してください。

インジェクションを行うポートでMTOM/XOP仕様形式の添付ファイルを利用できるように,フィーチャを有効化する場合の指定例を次に示します。

(5) 要求コンテキストのプロパティ変更

インジェクションを行うポートの要求コンテキストのプロパティを変更する際は,Webサービスクライアントの初期化処理での実行をお勧めします。初期化処理を実行するメソッドを次に示します。

サーブレットとして実装する場合
initメソッドまたはjavax.annotation.PostConstructアノテーションを指定したメソッド
EJBとして実装する場合
javax.annotation.PostConstructアノテーションを指定したメソッド
注意事項
複数スレッドでポートを共有するWebサービスクライアントで,複数スレッドの動作中にポートの要求コンテキストのプロパティを変更すると,通信が失敗したり,不正なSOAPメッセージが送信されたりします。このため,複数スレッドで共有するポートの要求コンテキストのプロパティの変更は,複数スレッドが動作する前に実行する必要があります。

サーブレットとして実装したWebサービスクライアントの,ポートの要求コンテキストのプロパティを変更する例を次に示します。

...
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.WebServiceRef;

import com.sample.AddNumbersImpl;
import com.sample.AddNumbersImplService;

public class TestClient extends HttpServlet {

   @WebServiceRef(AddNumbersImplService.class)
   AddNumbersImpl port;

   @Override
   public void init() {
       // 初期化処理で,要求コンテキストを設定する
       Map<String, Object> context = ((BindingProvider)port).getRequestContext();
       context.put("com.cosminexus.jaxws.connect.timeout", 60000);
   }
   ...
}