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アノテーションの指定例
- (2) Webサービスクライアントのインスタンス生成
- (3) ハンドラフレームワークの使用
- (4) フィーチャの有効化
- (5) 要求コンテキストのプロパティ変更
(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);
}
...
} |