11.4.5 注意事項
Webリソースクライアント実装時の注意事項について説明します。
- 〈この項の構成〉
(1) オブジェクトの再利用
Clientオブジェクトの生成には処理コストが掛かるので,一度生成したClientオブジェクトは再利用することをお勧めします。WebResourceオブジェクトを複数回生成したり,Clientクラスのメソッドを利用してWebリソースを複数回呼び出したりする場合に,Clientオブジェクトを複数回生成する必要はありません。
同様に,WebResourceの生成にも処理コストが掛かるので,一度生成したWebResourceオブジェクトは再利用することをお勧めします。同じWebリソース(URL)に対するHTTPリクエストやビルダを複数回生成する場合に,WebResourceオブジェクトを複数回生成する必要はありません。
ただし,Clientクラスの設定を行うメソッドや,オブジェクトを破棄するClientクラスのメソッドはスレッドセーフではありません。次の内容に注意してください。
-
複数スレッドでClientオブジェクトを共有する場合,共有するClientオブジェクトに対する設定は,複数スレッドが動作する前に実行してください。
-
Clientオブジェクトの破棄は,複数スレッドの動作が完了したあとに実行してください。
複数スレッドの動作中にこれらの操作を行った場合,通信が失敗したり,不正なHTTPリクエストが送信されたりすることがあります。
WebリソースクライアントをサーブレットやEJBなどで実装する場合は,サーブレットやEJBなどの初期化メソッドでClientオブジェクトを生成し,必要な設定を行ってください。Clientオブジェクトの破棄についても同様に,破棄メソッドでClientオブジェクトの破棄を行ってください。
サーブレットでRESTful Webサービス用クライアントAPIを利用する例を次に示します。
@WebServlet("/example") public class ClientServlet extends HttpServlet { // 共有されるClientオブジェクト private Client client = null; // 共有されるWebResourceオブジェクト private WebResource proxy = null; @PostConstruct public void postConstruct() { // RESTful Webサービス用クライアントAPIを利用するために // Clientオブジェクトを生成する this.client = Client.create(); // クライアントの設定: Clientオブジェクトからプロパティバッグを取得する Map<String, Object> properties = this.client.getProperties(); // クライアントの設定: 読み込みタイムアウトを設定する properties.put(ClientConfig.PROPERTY_READ_TIMEOUT, 10000); // ClientオブジェクトからWebResourceオブジェクトを生成する this.proxy = this.client.resource( "http://..." ); } @PreDestroy public void preDestory() { // Clientオブジェクトを破棄する if( this.client != null ){ this.client.destroy(); this.client = null; } } @Override public void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException{ ... ClientResponse clientResponse = null; // Invoke resource try { // クッキーを設定後,WebリソースからHTTPレスポンスを取得する Cookie cookie = new Cookie("cookie", "cookie%20value"); clientResponse = this.proxy.cookie(cookie).get(ClientResponse.class); }catch (Exception e) { printStackTrace( e, out ); } ... } }
RESTful Webサービス用クライアントAPIのスレッドセーフ性の詳細については,「25.16 RESTful Webサービス用クライアントAPIのスレッドセーフ性」を参照してください。
(2) プロキシ・SSL接続・ベーシック認証の設定
プロキシ,SSL接続,およびベーシック認証の設定については,それぞれ次の個所を参照してください。
-
プロキシの設定
-
SSL接続の設定
-
ベーシック認証の設定
(3) Windows環境での注意事項
Webリソースクライアントから大量のリクエストを送信するような環境では,次の例外が記録されることがあります。
java.net.BindException: Address already in use: connect [errno=10048, syscall=select]
この例外は,例えばサーブレットとして実装したWebリソースクライアントに対して大量のリクエストが到着したときなどに発生します。
このような場合は,次に示すどちらか,または両方の対策を実施してください。
-
OSで使用できるポート番号の範囲を広げる
例)レジストリのMaxUserPortの設定を見直す
-
TIME_WAITの継続時間を短くする
例)レジストリのTcpTimedWaitDelayの設定を見直す
ただし,OSのバージョンやエディション,セキュリティ更新プログラムの適用状況によって仕様が異なるため,詳細については各OSのドキュメントを参照してください。また,これらの設定はOS全体に影響が及ぶため,注意が必要です。
(4) リクエスト再送抑止
Webリソースクライアント側のJAX-RSエンジンは,JDKのHTTPクライアント実装を利用して通信しています。JDKのHTTPクライアント実装は,RFC 2616に反してHTTP通信でエラーが発生し,サーバから正しいレスポンスを受け取れなかった場合,一度だけリクエストを再送します。JDKのシステムプロパティを使用するとリクエストの再送を抑止できます。詳細は,「10.20 sun.net.www.http.HttpClientによるリクエスト再送抑止」を参照してください。なお,参照する場合は「Webサービスクライアント」を「RESTful Webサービスクライアント」に,「JAX-WSエンジン」を「JAX-RSエンジン」に読み替えてください。
(5) コマンドラインを利用したクライアントアプリケーションの実行
コマンドラインで動作するJavaアプリケーションをクライアントアプリケーションとして利用するときに必要な設定,コマンドラインの指定例,注意事項については,「10.14 コマンドラインを利用したクライアントアプリケーションの実行」を参照してください。なお,RESTful Webサービスクライアントでは,Javaアプリケーション用オプション定義ファイルに次のキーと値も追加してください。
add.class.path=<インストールディレクトリ>/jaxws/lib/cjjaxrs.jar