Hitachi

Cosminexus V11 アプリケーションサーバ Webサービス開発ガイド


11.4.5 注意事項

Webリソースクライアント実装時の注意事項について説明します。

〈この項の構成〉

(1) オブジェクトの再利用

Clientオブジェクトの生成には処理コストが掛かるので,一度生成したClientオブジェクトは再利用することをお勧めします。WebResourceオブジェクトを複数回生成したり,Clientクラスのメソッドを利用してWebリソースを複数回呼び出したりする場合に,Clientオブジェクトを複数回生成する必要はありません。

同様に,WebResourceの生成にも処理コストが掛かるので,一度生成したWebResourceオブジェクトは再利用することをお勧めします。同じWebリソース(URL)に対するHTTPリクエストやビルダを複数回生成する場合に,WebResourceオブジェクトを複数回生成する必要はありません。

ただし,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接続,およびベーシック認証の設定については,それぞれ次の個所を参照してください。

(3) Windows環境での注意事項

Webリソースクライアントから大量のリクエストを送信するような環境では,次の例外が記録されることがあります。

java.net.BindException: Address already in use: connect  [errno=10048, syscall=select]

この例外は,例えばサーブレットとして実装したWebリソースクライアントに対して大量のリクエストが到着したときなどに発生します。

このような場合は,次に示すどちらか,または両方の対策を実施してください。

ただし,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

(6) 通信失敗時のJava例外

Webサービスとの通信が失敗した場合,次の例外が記録されることがあります。

java.net.ConnectException: ["Connection refused: connect"または"接続を拒否されました"]

このメッセージは,OSや環境によって出力内容が異なる場合があります。