关闭CloseableHttpResponse/CloseableHttpClient的正确方法

11

我正在使用CloseableHttpResponse(来自apache-httpclient-4.5.3),但我不确定我是否使用正确,我看到一个没有投票的答案,建议在finally中使用EntityUtils.consume

CloseableHttpResponse response1 = httpclient.execute(httpGet);

try {

 System.out.println(response1.getStatusLine());

} finally {

 EntityUtils.consume(response1.getEntity());

CloseableHttpClient 是一个抽象类,虽然在这个 answer 中被使用,但它本身没有 close 方法可供调用:

CloseableHttpResponse response = httpclient.execute(httpget);
try {
    //do something
} finally {
    response.close();
}

目前我在send方法中使用try with resources处理CloseableHttpClient和CloseableHttpResponse。

我是否遗漏了任何资源的打开或错误使用任何资源?

private CloseableHttpResponse send()
            throws URISyntaxException, UnsupportedEncodingException, IOException, ClientProtocolException {
        URIBuilder uriBuilder = new URIBuilder(BASE_URL);
        HttpHost target = new HttpHost(uriBuilder.getHost(), uriBuilder.getPort(), uriBuilder.getScheme());
        HttpPost post = new HttpPost(uriBuilder.build());
        try (CloseableHttpClient httpClient = HttpClients.custom().build(); CloseableHttpResponse response = httpClient.execute(target, post)) {            
            return response;
        }
    

只是一条注释:CloseableHttpResponse response1 = httpclient.execute(httpGet),execute方法在5.2.1版本中已被弃用。 - cviniciusm
2个回答

18

有关详细信息,请参阅文档这里。从文档中引用伪代码,以下是分配/释放CloseableHttpClient实例的典型方法:

try (CloseableHttpClient httpclient = HttpClients.createDefault()) {
    <...>
}

对于CloseableHttpResponse同样适用:

try (CloseableHttpResponse response = httpclient.execute(httpget)) {
    <...>
}

现在,关于CloseableHttpClient中的close方法。 CloseableHttpClient是一个实现了Closeable接口的抽象类。也就是说,虽然它本身没有close方法,但扩展它的类必须要实现close方法。其中一个类是InternalHttpClient。您可以查看源代码以了解详细信息。

在Java7之前,需要显式关闭:

CloseableHttpClient httpclient = HttpClients.createDefault();
try {
    <...>
} finally {
    httpclient.close();
}

CloseableHttpResponse response = httpclient.execute(httpget);
try {
    <...>
} finally {
    response.close();
}

1
我的使用 try with resources 的方法同样可行吗? - user7294900
是的。有几种方法可以释放 Closeable 资源,其中之一是使用 try-with-resources。但是,如何关闭资源以及何时关闭取决于您的用例。 - atoMerz
不需要使用 EntityUtils.consume(response.getEntity()) 吗? - user7294900
@user7294900 如果您不确定代码是否始终会消耗整个响应消息内容,则可以使用此方法。而try-with-resources是正确的方式,但它并不能否定atoMerz所概述的基本原则。 - ok2c
@user7294900 那又怎样?响应会被运行时隐式关闭。 - ok2c
显示剩余4条评论

8
您可以使用 try(resource) 来避免 finally。

try (CloseableHttpResponse response = httpclient.execute(httpGet)) { ... }


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