10.21.1 サービスクラスおよびポートのインジェクション
J2EEサーバ上で動作するWebサービスクライアントの,次に示すフィールドおよびメソッドにjavax.xml.ws.WebServiceRefアノテーションを指定すると,J2EEサーバが,Webサービスクライアントのインスタンス生成時にサービスクラスおよびポートの生成とインジェクションを行います。javax.xml.ws.WebServiceRefアノテーションについては,「19.3 アノテーションのサポート範囲」を参照してください。
-
サービスクラス型およびポート型のフィールド(staticおよびfinalを除く)
-
サービスクラス型およびポート型を引数とするsetterメソッド(staticおよびfinalを除く)
javax.xml.ws.WebServiceRefアノテーションによるインジェクションの利用には,次のような利点があります。
-
アプリケーションの開発では,javax.xml.ws.WebServiceRefアノテーションによるインジェクションを利用しない場合に比べコーディング量を削減できるため,Webサービスクライアントの作成が容易になります。
-
J2EEアプリケーションの開始時にWebサービスクライアントのインスタンスを生成すると,ポートのインジェクションを利用しない場合に比べ,Webサービスクライアント実行時の性能を改善できます。
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アノテーションの指定例
javax.xml.ws.WebServiceRefアノテーションの指定例を次に示します。
-
フィールドへの指定例
... import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.xml.ws.WebServiceRef; import com.sample.AddNumbersImpl; import com.sample.AddNumbersImplService; public class TestClient extends HttpServlet { // サービスクラスの例 // サービスクラス型のフィールドにサービスクラスのインスタンスをインジェクトする @WebServiceRef private AddNumbersImplService service; // ポートの例 // ポート型のフィールドにポートのインスタンスをインジェクトする @WebServiceRef(AddNumbersImplService.class) private AddNumbersImpl port; @Override public void init() { // Webサービスクライアントの実行前にアプリケーションサーバがサービスクラスと // ポートをインジェクトするので,以下の処理は行う必要がない //service = new AddNumbersImplService(); //port = service.getAddNumbersImplPort(); } @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException { ...
-
setterメソッドへの指定例
... import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.xml.ws.WebServiceRef; import com.sample.AddNumbersImpl; import com.sample.AddNumbersImplService; public class TestClient extends HttpServlet { private AddNumbersImplService service; private AddNumbersImpl port; @Override public void init() { // アプリケーション開始時にアプリケーションサーバがsetterメソッドを使用して // サービスクラスとポートをインジェクトするので,以下の処理は行う必要がない //service = new AddNumbersImplService(); //port = service.getAddNumbersImplPort(); } // サービスクラスの例 @WebServiceRef public void setAddNumbersImplService(AddNumbersImplService service) { // 引数serviceにサービスクラスのインスタンスをインジェクトする this.service = service; } // ポートの例 @WebServiceRef(AddNumbersImplService.class) public void setAddNumbersImpl(AddNumbersImpl port) { // 引数portにポートのインスタンスをインジェクトする this.port = port; } @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException { ...
(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へのマッピングのカスタマイズ」を参照してください。
-
javax.xml.ws.soap.Addressing
-
javax.xml.ws.soap.MTOM
-
com.sun.xml.ws.developer.StreamingAttachment
インジェクションを行うポートでMTOM/XOP仕様形式の添付ファイルを利用できるように,フィーチャを有効化する場合の指定例を次に示します。
-
フィールドへの指定例
... import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.xml.ws.WebServiceRef; import com.sample.AddNumbersImpl; import com.sample.AddNumbersImplService; public class TestClient extends HttpServlet { // インジェクションを行うポートでMTOM/XOP仕様形式の添付ファイルを有効化 @MTOM @WebServiceRef(AddNumberImplService.class) private AddNumbersImpl port; @Override public void init() { ... } @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException { ...
-
setterメソッドへの指定例
... import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.xml.ws.WebServiceRef; import com.sample.AddNumbersImpl; import com.sample.AddNumbersImplService; public class TestClient extends HttpServlet { private AddNumbersImpl port; @Override public void init() { ... } // インジェクションを行うポートでMTOM/XOP仕様形式の添付ファイルを有効化 @MTOM @WebServiceRef(AddNumberImplService.class) public void setAddNumbersImpl(AddNumbersImpl port) { this.port = port; } @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException { ...
(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); } ... }