为什么Apache CloseableHttpResponse不会在关闭时使用实体?

时间:2017-06-10 05:18:04

标签: java apache apache-httpclient-4.x autocloseable

查看quick start guide,它提供了以下代码示例:

CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet("http://targethost/homepage");
CloseableHttpResponse response1 = httpclient.execute(httpGet);
// The underlying HTTP connection is still held by the response object
// to allow the response content to be streamed directly from the network socket.
// In order to ensure correct deallocation of system resources
// the user MUST call CloseableHttpResponse#close() from a finally clause.
// Please note that if response content is not fully consumed the underlying
// connection cannot be safely re-used and will be shut down and discarded
// by the connection manager. 
try {
    System.out.println(response1.getStatusLine());
    HttpEntity entity1 = response1.getEntity();
    // do something useful with the response body
    // and ensure it is fully consumed
    EntityUtils.consume(entity1);
} finally {
    response1.close();
}

上面代码中的两条评论说我们必须关闭

的响应对象
  

“正确释放系统资源”

  

“如果没有完全消耗响应内容,则无法安全地重复使用基础连接,并且连接管理器将关闭并放弃它。”

现在Apache非常友好地为我们实现了一个CloseableHttpResponse,这意味着我们可以使用try-with-resources块。但close方法只关闭响应对象,为什么它也不消耗实体?

1 个答案:

答案 0 :(得分:0)

因为在这一点上很难说调用者是否打算重用底层连接。在某些情况下,人们可能只想从大型响应体中读取一小块并立即终止连接。

换句话说,同样的事情一再发生:没有一种方法可以让每个人都开心。

在尝试保持底层连接处于活动状态时,代码段将确保正确的资源取消分配。

CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet("http://targethost/homepage");
CloseableHttpResponse response1 = httpclient.execute(httpGet);
try {
    System.out.println(response1.getStatusLine());
} finally {
    EntityUtils.consume(response1.getEntity());
}