Apache HttpClient TimeOut 設定的方式

  • Post category:javase

上次我的程式,要連線網站取得資料,但是,要限制連線時間,所以要設定超過時間的設定。整理一下 Apache HttpClient Timrout 設定的方式。

如何在HttpClient 5.x API設定超時的方式 HttpClient Timout囉!

新的 API 版本引入了配置超時的新方法。使用ConnectionConfig設定連接超時:

ConnectionConfig connConfig = ConnectionConfig.custom()
    .setConnectTimeout(timeout, TimeUnit.MILLISECONDS)
    .setSocketTimeout(timeout, TimeUnit.MILLISECONDS)
    .build();

下一步將是創建一個連接管理器並設置我們在上面創建的ConnectionConfig

BasicHttpClientConnectionManager cm = new BasicHttpClientConnectionManager();
cm.setConnectionConfig(connConfig);

如何在HttpClient 4.3設定超時的方式

可以在建立物件的過程中設定

int timeout = 5;
RequestConfig config = RequestConfig.custom()
  .setConnectTimeout(timeout * 1000)
  .setConnectionRequestTimeout(timeout * 1000)
  .setSocketTimeout(timeout * 1000).build();
CloseableHttpClient client = 
  HttpClientBuilder.create().setDefaultRequestConfig(config).build();

解釋一下程式中三種 Time 的差別

setConnectTimeout:與遠程主機建立連接的時間

setSocketTimeout:建立連接後等待數據的時間

setConnectionRequestTimeout:等待來自連接管理器/池的連接的時間

設定完成之後使用HttpClient

配置完成後,我們就可以使用客戶端進行HTTP請求了:

final HttpGet request = new HttpGet("http://www.javainsoft.com");

try (CloseableHttpClient client = HttpClientBuilder.create()
    .setDefaultRequestConfig(requestConfig)
    .setConnectionManager(cm)
    .build();

    CloseableHttpResponse response = (CloseableHttpResponse) client
        .execute(request, new CustomHttpClientResponseHandler())) {

    final int statusCode = response.getCode();
    assertThat(statusCode, equalTo(HttpStatus.SC_OK));
}

之前的Timeout設定,當與主機的連接將在 5 秒後超時。另外,如果建立了連接,但沒有收到數據,超時時間Timeout也會增加5 秒

即使在連線下載中,也要Timeout的設定方式

例如,下載一個可能很大的文件就屬於這一類。在這種情況下,連接可能會成功建立,數據可能會持續通過,但是,就是不能連線這麼久,該如何設定呢?

HttpClient沒有任何允許我們為請求設置總超時的配置;但是,它確實為請求提供了中止功能,因此我們可以利用該機制來實現一個簡單的超時機制:

HttpGet getMethod = new HttpGet("http://127.0.0.1:8080/httpclient-simple/api/bars/1");
getMethod.setConfig(requestConfig);

int hardTimeout = 5000; // milliseconds
TimerTask task = new TimerTask() {
    @Override
    public void run() {
        getMethod.abort();
    }
};
new Timer(true).schedule(task, hardTimeout);

try (CloseableHttpClient client = HttpClientBuilder.create()
    .setDefaultRequestConfig(requestConfig)
    .setConnectionManager(cm)
    .build();

    CloseableHttpResponse response = (CloseableHttpResponse) client
        .execute(getMethod, new CustomHttpClientResponseHandler())) {

    final int statusCode = response.getCode();
    System.out.println("HTTP Status of response: " + statusCode);
    assertThat(statusCode, equalTo(HttpStatus.SC_OK));
}

使用java.util.Timerjava.util.TimerTask來設置一個簡單的延遲任務,該任務在 5 秒後中止 HTTP GET 請求。

Httpclient 中 setConnectTimeout vs setConnectionRequestTimeout 差異

setConnectTimeout:與遠程主機建立連接的時間
setConnectionRequestTimeout:等待來自連接管理器/池的連接的時間

Httpclient 中 setConnectTimeout vs setSocketTimeout:差異

setSocketTimeout:建立連接後等待數據的時間
setConnectTimeout:與遠程主機建立連接的時間