使用HttpClient要注意下系统资源的释放,本文主要介绍使用HttpClient进行请求时,释放系统资源的方法及示例代码。

1、释放资源代码

为了确保正确释放系统资源,必须关闭与实体关联的内容流或响应本身:

CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpget = new HttpGet("http://localhost/");
CloseableHttpResponse response = httpclient.execute(httpget);
try {
    HttpEntity entity = response.getEntity();
    if (entity != null) {
        InputStream instream = entity.getContent();
        try {
            // do something useful
        } finally {
            instream.close();
        }
    }
} finally {
    response.close();
}

2、关闭内容流和关闭响应之间的区别

前者将通过消耗实体内容来尝试使基础连接保持活动状态,而后者立即关闭并丢弃该连接。

请注意,HttpEntity#writeTo(OutputStream) 一旦实体被完全写出,还需要该方法来确保适当释放系统资源。如果此方法java.io.InputStream通过调用 获得的实例 HttpEntity#getContent(),则还应在finally子句中关闭流。

使用流式实体时,可以使用该 EntityUtils#consume(HttpEntity)方法来确保实体内容已被完全消耗,并且基础流已关闭。

但是,在某些情况下,仅需要检索整个响应内容的一小部分,并且消耗剩余内容并使连接可重用的性能损失过高,在这种情况下,可以通过关闭响应(response)来终止内容流。如下,

CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpget = new HttpGet("http://localhost/");
CloseableHttpResponse response = httpclient.execute(httpget);
try {
    HttpEntity entity = response.getEntity();
    if (entity != null) {
        InputStream instream = entity.getContent();
        int byteOne = instream.read();
        int byteTwo = instream.read();
        // Do not need the rest
    }
} finally {
    response.close();
}

上面代码,连接将不会被重用,但是它所拥有的所有级别资源都将被正确地释放。

相关文档http://hc.apache.org/httpcomponents-client-ga/tutorial/html/fundamentals.html#d5e37