推荐用try-with-resources关闭CloseableHttpResponse或HttpResponse,而非仅关InputStream;前者自动释放连接和资源,后者需提前读取headers且流必须消费完。

Java 的 try-with-resources 是处理 HTTP 响应流(如 HttpURLConnection.getInputStream() 或 CloseableHttpClient 返回的响应)时自动关闭资源的推荐方式,前提是所用资源实现了 AutoCloseable 接口。
确保响应流本身可自动关闭
HTTP 响应体流(如 InputStream)本身是 AutoCloseable 的,但**仅关闭流通常不够**——它不会关闭底层连接或释放响应对象。真正需要关闭的是整个 HttpResponse(Apache HttpClient)或 HttpURLConnection 实例(JDK 自带)。
- 使用 Apache HttpClient 时,
CloseableHttpResponse实现了AutoCloseable,应在 try-with-resources 中直接声明它;其.getEntity().getContent()返回的InputStream会随响应一起关闭。 - 使用 JDK HttpURLConnection 时,
HttpURLConnection本身 不实现AutoCloseable,但它的getInputStream()和getErrorStream()返回的流是。不过,仅关闭流不能保证连接被释放(尤其在未读完响应体时),因此更稳妥的做法是配合disconnect(),或改用更高层封装(如HttpClient新 API)。
Apache HttpClient 示例(推荐)
这是最清晰、最安全的方式:
try (CloseableHttpClient client = HttpClients.createDefault();
CloseableHttpResponse response = client.execute(new HttpGet("https://httpbin.org/get"))) {
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_OK) {
try (InputStream is = response.getEntity().getContent()) {
// 读取并处理响应体,例如:IOUtils.toString(is, StandardCharsets.UTF_8)
}
}
} catch (IOException e) {
// 处理网络或 IO 异常
}
注意:CloseableHttpResponse 的 close() 方法会自动调用 EntityUtils.consume(entity)(如果未手动消费),确保流被读完并释放连接。
JDK 11+ HttpClient(新 API)示例
新 HttpClient 的 HttpResponse 不实现 AutoCloseable,但它的 bodyAsStream() 返回的 InputStream 是。若需自动关闭流,可这样写:
HttpClient client = HttpClient.newBuilder().build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://httpbin.org/get"))
.build();
try (HttpResponse<inputstream> response = client.send(request, HttpResponse.BodyHandlers.ofInputStream())) {
if (response.statusCode() == 200) {
try (InputStream is = response.body()) {
// 使用 is 读取内容
}
}
}</inputstream>
⚠️ 注意:这里 response.body() 返回的流必须在 try 内消费完毕,否则可能阻塞连接复用;且该流关闭后,response 对象本身不再提供其他信息(如 headers 需提前读取)。
避免常见错误
-
不要只对 InputStream 使用 try-with-resources 而忽略响应对象:例如
try (InputStream is = conn.getInputStream()) { ... }—— 这无法释放HttpURLConnection,可能导致连接泄漏。 -
不要在流关闭后再读响应头或状态码:资源关闭后部分属性可能失效(尤其 Apache HttpClient 中,
response.getStatusLine()在close()后仍可用,但response.getEntity()可能为 null)。 -
异常时也要确保关闭:try-with-resources 会在正常退出和异常退出时都调用
close(),无需额外finally块。
核心原则:把生命周期最长、语义上“拥有”其他资源的那个对象(如 CloseableHttpResponse 或 HttpResponse)放进 try-with-resources,让关闭逻辑由框架统一管理,而不是手动关流。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











