Apache HttpComponents HttpClient 超时

50
5个回答

109

在Apache Http Client 4.3版本中,配置进行了重构(再次)。新的配置方式如下:

RequestConfig.Builder requestBuilder = RequestConfig.custom();
requestBuilder.setConnectTimeout(timeout);
requestBuilder.setConnectionRequestTimeout(timeout);

HttpClientBuilder builder = HttpClientBuilder.create();     
builder.setDefaultRequestConfig(requestBuilder.build());
HttpClient client = builder.build();

11
你需要加入requestBuilder.setSocketTimeout(timeout);。请注意,timeout应该是毫秒为单位的! - Stefan
6
请注意,调用 setConnectTimeout()setConnectionRequestTimeout() 与设置 CONNECTION_TIMEOUTSO_TIMEOUT(如所述问题中)不同。您可能需要使用 setConnectTimeout()setSocketTimeout() - Jonik
7
此外,该构建器允许您链接这些语句,从而使代码更简洁: RequestConfig config = RequestConfig.custom().setConnectTimeout(timeout).setSocketTimeout(timeout).build(); - Jonik
构建器对象通常提供流畅接口,这一点毫无不好。RequestConfig.custom().setConnectionTimeout(timeout).setConnectionRequestTimeout(timeout).build() 就能构建你所需的 RequestConfig。同样适用于 HttpClient 的构建… - Peter Perháč

13

在HttpClient 4.3版本中,你可以使用以下示例...假设为5秒钟

int timeout = 5;
RequestConfig config = RequestConfig.custom()
  .setConnectTimeout(timeout * 1000)
  .setConnectionRequestTimeout(timeout * 1000)
  .setSocketTimeout(timeout * 1000).build();
CloseableHttpClient client = 
  HttpClientBuilder.create().setDefaultRequestConfig(config).build();
HttpGet request = new HttpGet("http://localhost:8080/service"); // GET Request
response = client.execute(request);

9

@jontro的答案是正确的,但是提供一个代码片段来说明如何实现总是更好。有两种方法可以实现:

版本1:为每个参数设置10秒超时时间:

HttpClient httpclient = new DefaultHttpClient();
// this one causes a timeout if a connection is established but there is 
// no response within 10 seconds
httpclient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 10 * 1000);

// this one causes a timeout if no connection is established within 10 seconds
httpclient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 10 * 1000);

// now do the execute:
HttpGet httpget = new HttpGet(URL);
HttpResponse response = httpclient.execute(httpget);



第二版: 同时为这些参数设置10秒超时:

HttpParams params = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params, 10 * 1000);
HttpConnectionParams.setSoTimeout(params, 10 * 1000);

HttpClient httpclient = new DefaultHttpClient(params);
HttpGet httpget = new HttpGet(URL);
HttpResponse response = httpclient.execute(httpget);

另外还可以查看静态方法HttpConnectionParams.setConnectionTimeout()和HttpConnectionParams.setSoTimeout(),它们提供了一种稍微更方便的方式来完成同样的事情。 - dnault
1
.getParams()现在已经被弃用并抛出UnsupportedOperationException异常。 - user177800

5
第2.5节中,您可以看到如何设置CONNECTION_TIMEOUT参数的示例。
CONNECTION_TIMEOUT是等待初始连接的时间,而SO_TIMEOUT是在建立连接后等待读取数据包的超时时间。

4

我为整个请求设置了一个严格的时间限制,以解决java.net.SocketInputStream.socketRead0问题。

private static final ScheduledExecutorService SCHEDULED_EXECUTOR = Executors.newSingleThreadScheduledExecutor()

HttpGet request = new HttpGet("http://www.example.com")
final Runnable delayedTask = new Runnable() {
    @Override
    public void run() {
        request.abort()
    }
}
SCHEDULED_EXECUTOR.schedule(delayedTask, 100000, TimeUnit.MILLISECONDS)

不错的模式。如果请求成功完成或因其他原因失败,则值得取消延迟任务。 - Vic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接