1. 概要

Apache HttpClient は、最新のHTTP標準のクライアント側を実装する効率的で機能豊富なパッケージを提供する人気のあるJavaライブラリです。 ライブラリは拡張用に設計されており、ベースHTTPメソッドを強力にサポートします。

このチュートリアルでは、ApacheHttpClientAPIの設計について説明します。 HttpClientCloseableHttpClientの違いについて説明します。 さらに、HttpClientsまたはHttpClientBuilderを使用してCloseableHttpClientインスタンスを作成する方法を確認します。

最後に、カスタムコードで使用する必要がある前述のAPIをお勧めします。 また、どのAPIクラスが Closeable インターフェイスを実装しているかを確認します。したがって、リソースを解放するためにインスタンスを閉じる必要があります。

2. APIデザイン

まず、APIがどのように設計されているかを見て、その高レベルのクラスとインターフェースに焦点を当てましょう。 以下のクラス図では、HTTPリクエストのクラシック実行とHTTPレスポンスの処理に必要なAPIの一部を示しています。

さらに、Apache HttpClient APIは、非同期 HTTP要求/応答交換、およびRxJavaを使用したリアクティブメッセージ交換もサポートします。

3. HttpClient CloseableHttpClient

HttpClient は、HTTPリクエスト実行の基本的なコントラクトを表す高レベルのインターフェイスです。 リクエストの実行プロセスに制限はありません。 また、状態管理、認証、個々のクライアント実装へのリダイレクトなどの詳細を残します。

任意のクライアント実装をHttpClientインターフェイスにキャストできます。 したがって、これを使用して、デフォルトのクライアント実装を介して基本HTTP要求を実行できます。

HttpClient httpClient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet(serviceUrl);
HttpResponse response = httpClient.execute(httpGet);
assertThat(response.getCode()).isEqualTo(HttpStatus.SC_OK);

ただし、上記のコードでは、SonarQubeブロッカーの問題が発生します。 その理由は、デフォルトのクライアント実装が Closeable HttpClientのインスタンスを返すためです。これには閉じる必要があります。

CloseableHttpClient は、HttpClientインターフェイス基本実装を表す抽象クラスです。 ただし、Closeableインターフェイスも実装しています。 したがって、使用後にすべてのインスタンスを閉じる必要があります。 try-with-resources を使用するか、finally句でcloseメソッドを呼び出すことにより、これらを閉じることができます。

try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
    HttpGet httpGet = new HttpGet(serviceUrl);
    HttpResponse response = httpClient.execute(httpGet);
    assertThat(response.getCode()).isEqualTo(HttpStatus.SC_OK);
}

したがって、カスタムコードでは、HttpClientインターフェイスではなくCloseableHttpClientクラスを使用する必要があります。

4. HttpClients対。 HttpClientBuilder

上記の例では、 HttpClients クラスの静的メソッドを使用して、デフォルトのクライアント実装を取得しました。 HttpClients は、CloseableHttpClientインスタンスを作成するためのファクトリメソッドを含むユーティリティクラスです

CloseableHttpClient httpClient = HttpClients.createDefault();

私たちは同じことを使用して達成することができます HttpClientBuilder クラス 。 HttpClientBuilder は CloseableHttpClientインスタンスを作成するためのBuilderデザインパターンの実装

CloseableHttpClient httpClient = HttpClientBuilder.create().build();

内部的には、HttpClientsHttpClientBuilderを使用してクライアント実装インスタンスを作成します。 したがって、カスタムコードではHttpClientsを使用することをお勧めします。 それがより高いレベルのクラスであることを考えると、その内部は新しいリリースで変更される可能性があります。

5. 資源管理

CloseableHttpClient インスタンスがスコープ外になったら閉じる必要がある理由は、関連する接続マネージャーをシャットダウンするためです。 さらに、システムリソースの適切な割り当て解除を確実にするためにCloseableHttpResponseを使用する必要があります

5.1. クローズ可能HttpResponse

CloseableHttpResponse は、ClassicHttpResponseインターフェイスを実装するクラスです。 ただし、 ClassicHttpResponse は、 HttpResponse HttpEntityContainer 、およびCloseableインターフェイスも拡張します。

基盤となるHTTP接続は、応答オブジェクトによって保持され、応答コンテンツをネットワークソケットから直接ストリーミングできるようにします。 したがって、カスタムコードでは、HttpResponseインターフェイスの代わりにCloseableHttpResponseクラスを使用する必要があります。 また、応答を消費したら、必ずcloseメソッドを呼び出す必要があります。

try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
    HttpGet httpGet = new HttpGet(serviceUrl);
    try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
        HttpEntity entity = response.getEntity();
        EntityUtils.consume(entity);
    }
}

応答コンテンツが完全に消費されていない場合、基盤となる接続を安全に再利用できないことに注意してください。 このような状況では、接続はシャットダウンされ、接続マネージャーによって破棄されます。

5.2. クライアントの再利用

CloseableHttpClient インスタンスを閉じて、リクエストごとに新しいインスタンスを作成すると、コストのかかる操作になる可能性があります。 代わりに、CloseableHttpClientの単一のインスタンスを再利用して複数のリクエストを送信できます

try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
    HttpGet httpGetOne = new HttpGet(serviceOneUrl);
    try (CloseableHttpResponse responseOne = httpClient.execute(httpGetOne)) {
        HttpEntity entityOne = responseOne.getEntity();
        EntityUtils.consume(entityOne);
        assertThat(responseOne.getCode()).isEqualTo(HttpStatus.SC_OK);
    }

    HttpGet httpGetTwo = new HttpGet(serviceTwoUrl);
    try (CloseableHttpResponse responseTwo = httpClient.execute(httpGetTwo)) {
        HttpEntity entityTwo = responseTwo.getEntity();
        EntityUtils.consume(entityTwo);
        assertThat(responseTwo.getCode()).isEqualTo(HttpStatus.SC_OK);
    }
}

その結果、内部で関連付けられた接続マネージャーをシャットダウンして新しい接続マネージャーを作成することを回避できます。

6. 結論

この記事では、 we は、Java用の人気のあるクライアント側HTTPライブラリであるApacheHttpClientの従来のHTTPAPIについて説明しました。

HttpClientCloseableHttpClientの違いを学びました。 また、カスタムコードではCloseableHttpClientを使用することをお勧めします。 次に、HttpClientsまたはHttpClientBuilderを使用してCloseableHttpClientインスタンスを作成する方法を確認しました。

最後に、CloseableHttpClientクラスとCloseableHttpResponseクラスの両方がCloseableインターフェイスを実装していることを確認しました。 リソースを解放するには、インスタンスを閉じる必要があることがわかりました。

いつものように、完全なソースコードはGitHubから入手できます。