Apache HttpClient APIのCloseableHttpClientとHttpClientの違いは何ですか?


83

弊社が開発したアプリケーションを勉強しています。ApacheHttpClientライブラリを使用します。ソースコードでは、HttpClientクラスを使用してサーバーに接続するインスタンスを作成します。

Apache HttpClientについて知りたいので、この一連の例を紹介しました。すべての例では、のCloseableHttpClient代わりにを使用していますHttpClient。だから私CloseableHttpClientはの拡張バージョンだと思いますHttpClient。この場合、2つの質問があります。

  • これら2つの違いは何ですか?
  • 新しい開発に使用することをお勧めするクラスはどれですか?

7
ドキュメントは私にはかなり明確に思えます:「Closeableも実装するHttpClientの基本実装」-HttpClientはインターフェースです。CloseableHttpClientは抽象クラスですが、AutoCloseableを実装しているため、try-with-resourcesステートメントで使用できます。
Jon Skeet 2014

3
@JonSkeetそれだけは明らかですが、HttpClientインスタンスを閉じることはどれほど重要ですか?それが重要な場合、なぜclose()メソッドは基本的なインターフェースの一部ではないのですか?
ジュール

3
@Jules:HttpClientについて、それに答えるのに十分な知識がないのではないかと思います:(
Jon Skeet

基礎となる接続が接続マネージャーに自動的に解放されるため、closeを基本インターフェイスの一部にする必要はありません
JerilKuruvila19年

回答:


98
  • HttpClient APIの主なエントリポイントは、HttpClientインターフェイスです。
  • HttpClientの最も重要な機能は、HTTPメソッドを実行することです。
  • HTTPメソッドの実行には、1つまたは複数のHTTP要求/ HTTP応答交換が含まれ、通常はHttpClientによって内部的に処理されます。

  • CloseableHttpClientは、java.io.Closeableも実装するHttpClientの基本実装である抽象クラスです。
  • 最も単純な形式のリクエスト実行プロセスの例を次に示します。

    CloseableHttpClient httpclient = HttpClients.createDefault();
    HttpGet httpget = new HttpGet( "http:// localhost /");
    CloseableHttpResponse応答= httpclient.execute(httpget);
    {を試してください
        //何かをする
    } 最後に {
        response.close();
    }

  • HttpClientリソースの割り当て解除:インスタンスCloseableHttpClientが不要になり、スコープ外になりそうな場合は、CloseableHttpClient#close()メソッドを呼び出して、インスタンスに関連付けられている接続マネージャーをシャットダウンする必要があります。

    CloseableHttpClient httpclient = HttpClients.createDefault();
    {を試してください
        //何かをする
    } 最後に {
        httpclient.close();
    }

基本については、リファレンスを参照してください。


@Scadge Java 7以降、try-with-resourcesステートメント使用すると、ステートメントの最後で各リソースが確実に閉じられます。クライアントと各応答の両方に使用できます

try(CloseableHttpClient httpclient = HttpClients.createDefault()){

    // e.g. do this many times
    try (CloseableHttpResponse response = httpclient.execute(httpget)) {
    //do something
    }

    //do something else with httpclient here
}

57
この答えは一種の論点先取です。HttpClientでclose()を呼び出すと、他の方法では発生しないことが発生しますか?適切な時間/場所でclose()を呼び出さないと、接続がリークしますか?close()を呼び出すと、本当に必要のないときに再接続するため、パフォーマンスに時期尚早に影響しますか?
gilbertpilz 2015

4
この質問への答えをhttpclientのコードで調べました。答えは、closeメソッドを使用して内部状態を閉じることです。(httpclient lib内の)HTTPClientの実装の一部は、プールされた接続にPooledHttpClientConnectionManagerなどの永続リソースを使用するように構成できます。このようなメソッドがないと、必要に応じてこれらのリソースをクリーンアップできません。
Deadron 2017年

上記の例のhttpget
@SugarPudi

ここで抽象クラス(CloseableHttpClient)のメソッドを呼び出すにはどうすればよいですか?最初に具体的なサブクラスを作成するべきではありませんか?
illcar 2017

@illcarコンセプトを理解するために、この回答を確認してくださいstackoverflow.com/a/4321402/2830834
Sagar Pudi

26

同じ質問がありました。他の答えは、close()が本当に必要な理由に対処していないようです?また、Opは、HttpClientなどを使用するための好ましい方法を見つけるのに苦労しているようでした。


Apacheによると:

// The underlying HTTP connection is still held by the response object
// to allow the response content to be streamed directly from the network socket.
// In order to ensure correct deallocation of system resources
// the user MUST call CloseableHttpResponse#close() from a finally clause.

さらに、関係は次のようになります。

HttpClient (インターフェース)

実装者:

CloseableHttpClient -スレッドセーフ。

DefaultHttpClient-ThreadSafeは非推奨ですがHttpClientBuilder代わりに使用してください。

HttpClientBuilder-ThreadSafeではありませんが、ThreadSafeを作成しますCloseableHttpClient

  • CUSTOMの作成に使用しますCloseableHttpClient

HttpClients-ThreadSafeではありませんが、ThreadSafeを作成しますCloseableHttpClient

  • DEFAULTまたはMINIMALを作成するために使用しますCloseableHttpClient

Apacheによる推奨される方法:

CloseableHttpClient httpclient = HttpClients.createDefault();

彼らが与えるhttpclient.close()finally節で行い、またResponseHandler同様に利用します。


別の方法として、mkyongのやり方も少し興味深いです。

HttpClient client = HttpClientBuilder.create().build();

彼はclient.close()呼び出しを表示しませんclientが、まだのインスタンスであるため、必要だと思いますCloseableHttpClient


15

他の答えは、なぜclose()本当に必要なのかを扱っていないようです。* 2

「HttpClientリソースの割り当て解除」という答えに疑問があります。

これは古い3.xhttpcomponents docに記載されていますが、これは古く、4.xHCとは大きく異なります。それに加えて、説明は非常に簡潔なので、この基礎となるリソースが何であるかはわかりません。

4.5.2リリースのソースコードについて調査したところ、の実装はCloseableHttpClient:close()基本的に接続マネージャーを閉じるだけであることがわかりました。

(参考)そのため、共有PoolingClientConnectionManagerクライアントと通話クライアントを使用するとclose()、例外java.lang.IllegalStateException: Connection pool shut downが発生します。回避するために、setConnectionManagerShared動作します。

私はすべての要求の後にしたくないCloseableHttpClient:close()

以前は、リクエストを実行するときに新しいhttpクライアントインスタンスを作成し、最後にそれを閉じていました。この場合、を呼び出さない方がよいでしょうclose()。接続マネージャに「共有」フラグがない場合はシャットダウンされるため、単一の要求にはコストがかかりすぎます。

実際、Apache HC 4.5のClojureラッパーであるライブラリclj-httpでも、まったく呼び出さclose()れないことがわかりました。requestファイルcore.cljのfuncを参照してください


1
setConnectionManagerSharedを使用して、すべてのリクエストの後にclose()を呼び出すよりも優れている理由を明確にできますか?
zyfo2 2017

9

ライブラリHttpClientインターフェイスの次のメジャーバージョンでは、を拡張する予定Closeableです。それまではCloseableHttpClient、以前の4.xバージョン(4.0、4.1、および4.2)との互換性が必要ない場合に使用することをお勧めします。


8

HttpClientクラスではなく、インターフェースです。自分の思い通りに開発に使うことはできません。

必要なのは、HttpClientインターフェイスを実装するクラスですCloseableHttpClient。つまり、です。


2

CloseableHttpClientはhttpclientライブラリの基本クラスであり、すべての実装で使用されます。他のサブクラスは、ほとんどの場合非推奨です。

HttpClientこのクラスと他のクラスのためのインタフェースです。

次にCloseableHttpClient、コードでを使用し、を使用して作成する必要がありますHttpClientBuilder。特定の動作を追加するためにクライアントをラップする必要がある場合は、でラップする代わりに、要求と応答のインターセプターを使用する必要がありHttpClientます。

この回答は、httpclient-4.3のコンテキストで提供されました。


0

ジョンスキートは言った:

ドキュメントは私にはかなり明確に思えます:「Closeableも実装するHttpClientの基本実装」-HttpClientはインターフェースです。CloseableHttpClientは抽象クラスですが、AutoCloseableを実装しているため、try-with-resourcesステートメントで使用できます。

しかし、ジュールは尋ねました:

@JonSkeetそれだけは明らかですが、HttpClientインスタンスを閉じることはどれほど重要ですか?それが重要な場合、close()メソッドが基本的なインターフェースの一部ではないのはなぜですか?

ジュールへの回答

実行するたびに基になる接続が接続マネージャーに自動的に解放されるため、closeを基本インターフェイスの一部にする必要はありません。

try-with-resourcesステートメントに対応するため。Closeableの実装は必須です。したがって、CloseableHttpClientに含めました。

注意:

CloseableHttpClientを拡張しているAbstractHttpClientのcloseメソッドは非推奨であり、そのソースコードを見つけることができませんでした。


これはまだ「HttpClientインスタンスを閉じることがどれほど重要か」と答えていないようです。
Vivek Chavda
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.