CloseableHttpResponse.close()和httpPost.releaseConnection()之间有什么区别?

wya*_*ang 12 java httpclient

CloseableHttpResponse response = null;
try {
    // do some thing ....
    HttpPost request = new HttpPost("some url");
    response = getHttpClient().execute(request);
    // do some other thing ....
} catch(Exception e) {
    // deal with exception
} finally {
    if(response != null) {
        try {
            response.close(); // (1)
        } catch(Exception e) {}
        request.releaseConnection(); // (2)
    }
}
Run Code Online (Sandbox Code Playgroud)

我已经提出了如上所述的http请求.

为了释放底层连接,调用(1)和(2)是否正确?两个调用之间有什么区别?

Mat*_*att 18

简短回答:

request.releaseConnection()正在释放底层HTTP连接以允许它被重用.response.close()正在关闭流(不是连接),此流是我们从网络套接字流式传输的响应内容.

答案很长:

任何最新版本> 4.2甚至可能在此之前要遵循的正确模式是不使用releaseConnection.

request.releaseConnection() 发布底层的httpConnection,以便可以重用请求,但Java doc说:

一种简化从HttpClient 3.1 API迁移的便捷方法......

我们确保响应内容被完全消耗,而不是释放连接,这反过来确保连接被释放并准备好重用.一个简短的例子如下所示:

CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet("http://targethost/homepage");
CloseableHttpResponse response1 = httpclient.execute(httpGet);
try {
    System.out.println(response1.getStatusLine());
    HttpEntity entity1 = response1.getEntity();
    // do something useful with the response body
    String bodyAsString = EntityUtils.toString(exportResponse.getEntity());
    System.out.println(bodyAsString);
    // and ensure it is fully consumed (this is how stream is released.
    EntityUtils.consume(entity1);
} finally {
    response1.close();
}
Run Code Online (Sandbox Code Playgroud)

  • 嗨,马特,有什么参考吗?关于如何释放连接的文档一点都不清楚,例如通过response.close或httpclient.close.所有示例都只包含前者,所以看起来这已经足够了,但只是为了确定.你也可以解释为什么EntityUtils.consume甚至在EntityUtils.toString之后是必要的,它应该耗尽完整的输入流? (5认同)
  • 如果用例是通过在finally块中使用实体来安全地释放连接,那么你可以使用EntityUtils.consumeQuietly().(我正在使用httpcore 4.4.6) (3认同)
  • 您应该将EntityUtils.consumeQuietly放置在finally块中。我们看到了这样一种情况,即由于未读取其contentEntity,因此未释放使用HttpPost的池化连接。一个测试案例表明,这与内存泄漏问题直接相关。 (2认同)