首页 文章

Apache HttpClient超时

提问于
浏览
45

有没有办法为HttpClient的整个执行指定超时?

我尝试过以下方法:

httpClient.getParams().setParameter("http.socket.timeout", timeout * 1000);
httpClient.getParams().setParameter("http.connection.timeout", timeout * 1000);
httpClient.getParams().setParameter("http.connection-manager.timeout", new Long(timeout * 1000));
httpClient.getParams().setParameter("http.protocol.head-body-timeout", timeout * 1000);

它实际上工作正常,除非远程主机发回数据 - 即使是一个字节/秒 - 它将继续永远读取!但我想在10秒内中断连接,无论主机是否响应 .

6 回答

  • 1

    目前无法设置该类型的最大请求持续时间:基本上您想要说 I don't care whether or not any specific request stage times out, but the entire request must not last longer than 15 seconds (例如) .

    最好的办法是运行一个单独的计时器,当它到期时,获取HttpClient实例使用的连接管理器并关闭连接,这应该终止链接 . 如果这对您有用,请告诉我 .

  • -3

    对于较新版本的httpclient(例如http组件4.3 - https://hc.apache.org/httpcomponents-client-4.3.x/index.html):

    int CONNECTION_TIMEOUT_MS = timeoutSeconds * 1000; // Timeout in millis.
    RequestConfig requestConfig = RequestConfig.custom()
        .setConnectionRequestTimeout(CONNECTION_TIMEOUT_MS)
        .setConnectTimeout(CONNECTION_TIMEOUT_MS)
        .setSocketTimeout(CONNECTION_TIMEOUT_MS)
        .build();
    
    HttpPost httpPost = new HttpPost(URL);
    httpPost.setConfig(requestConfig);
    
  • 29

    按照Femi的建议,工作正常 . 谢谢!

    Timer timer = new Timer();
    timer.schedule(new TimerTask() {
        public void run() {
            if(getMethod != null) {
                getMethod.abort();
            }
        }
    }, timeout * 1000);
    
  • 13

    基于其他答案,我的解决方案是使用 HttpRequestInterceptor 将中止运行添加到每个请求 . 我换了 Timer 换了 ScheduledExecutorService .

    public class TimeoutInterceptor implements HttpRequestInterceptor {
    
    private int requestTimeout = 1 * DateTimeConstants.MILLIS_PER_MINUTE;
    
    private ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
    
    public TimeoutInterceptor() {  }
    
    public TimeoutInterceptor(final int requestTimeout) {
        this.requestTimeout = requestTimeout;
    }
    
    @Override
    public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException {
        if (request instanceof AbstractExecutionAwareRequest) {
            final AbstractExecutionAwareRequest abortableRequest = (AbstractExecutionAwareRequest) request;
            setAbort(abortableRequest);
        } else if (request instanceof HttpRequestWrapper) {
            HttpRequestWrapper wrapper = (HttpRequestWrapper) request;
            this.process(wrapper.getOriginal(), context);
        }
    
    }
    
    /**
     * @param abortableRequest
     */
    private void setAbort(final AbstractExecutionAwareRequest abortableRequest) {
        final SoftReference<AbstractExecutionAwareRequest> requestRef = new SoftReference<AbstractExecutionAwareRequest>(abortableRequest);
    
        executorService.schedule(new Runnable() {
    
            @Override
            public void run() {
                AbstractExecutionAwareRequest actual = requestRef.get();
                if (actual != null && !actual.isAborted()) {
                    actual.abort();
                }
            }
        }, requestTimeout, TimeUnit.MILLISECONDS);
    
    }
    
    public void setRequestTimeout(final int requestTimeout) {
        this.requestTimeout = requestTimeout;
    }
    }
    
  • 53

    在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);
    
  • 2

    这也是有效的:

    HttpClient client = new DefaultHttpClient();
    HttpConnectionParams.setConnectionTimeout(client.getParams(), timeout * 1000);
    HttpConnectionParams.setSoTimeout(client.getParams(), timeout * 1000);
    

相关问题