我正在研究由我们公司开发的应用程序。它使用Apache HttpClient库。在源代码中,它使用HttpClient
该类来创建实例以连接到服务器。
我想了解Apache HttpClient,并且已经看过这组示例。所有示例均使用CloseableHttpClient
代替HttpClient
。所以我认为CloseableHttpClient
是的扩展版本HttpClient
。如果是这种情况,我有两个问题:
- 两者有什么区别?
- 建议为我的新开发使用哪个课程?
我正在研究由我们公司开发的应用程序。它使用Apache HttpClient库。在源代码中,它使用HttpClient
该类来创建实例以连接到服务器。
我想了解Apache HttpClient,并且已经看过这组示例。所有示例均使用CloseableHttpClient
代替HttpClient
。所以我认为CloseableHttpClient
是的扩展版本HttpClient
。如果是这种情况,我有两个问题:
HttpClient
实例有多重要?如果重要,为什么该close()
方法不属于基本接口?
Answers:
这是最简单形式的请求执行过程示例:
CloseableHttpClient httpclient = HttpClients.createDefault(); HttpGet httpget =新的HttpGet(“ http:// localhost /”); CloseableHttpResponse响应= httpclient.execute(httpget); 尝试{ //做一点事 }最后{ response.close(); }
HttpClient资源的释放:当不再需要实例CloseableHttpClient并且将要超出范围时,必须通过调用CloseableHttpClient#close()方法来关闭与其关联的连接管理器。
CloseableHttpClient httpclient = HttpClients.createDefault(); 尝试{ //做一点事 }最后{ httpclient.close(); }
请参阅参考资料以学习基础知识。
@Scadge自Java 7起,使用try-with-resources语句可确保在语句末尾关闭每个资源。它可以用于客户端和每个响应
try(CloseableHttpClient httpclient = HttpClients.createDefault()){
// e.g. do this many times
try (CloseableHttpResponse response = httpclient.execute(httpget)) {
//do something
}
//do something else with httpclient here
}
httpget
也
有同样的问题。其他答案似乎没有解决为什么close()确实是必要的?而且,Op似乎在努力寻找与HttpClient等一起使用的首选方式。
根据Apache的说法:
// 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.
另外,关系如下:
HttpClient
(接口)实施者:
CloseableHttpClient
-线程安全。
DefaultHttpClient
-已弃用ThreadSafe BUT ,请HttpClientBuilder
改用。
HttpClientBuilder
-不是ThreadSafe,而是创建ThreadSafeCloseableHttpClient
。
- 用于创建CUSTOM
CloseableHttpClient
。
HttpClients
-不是ThreadSafe,而是创建ThreadSafeCloseableHttpClient
。
- 用于创建默认或最小
CloseableHttpClient
。
根据Apache的首选方式:
CloseableHttpClient httpclient = HttpClients.createDefault();
这个例子他们httpclient.close()
在finally
子句中给出也可以使用ResponseHandler
。
另外,mkyong的执行方式也很有趣:
HttpClient client = HttpClientBuilder.create().build();
他没有显示client.close()
电话,但我认为有必要,因为client
它仍然是的实例CloseableHttpClient
。
其他答案似乎没有解决为什么close()
真正必要的问题?* 2
在旧的3.x httpcomponents doc中提到了该文档,该文档很早就与4.x HC有很多区别。此外,解释如此简短,以至于没有说明该基础资源是什么。
我对4.5.2发布的源代码进行了一些研究,发现CloseableHttpClient:close()
基本上只关闭其连接管理器的实现。
(FYI)这就是为什么当您使用共享PoolingClientConnectionManager
并呼叫客户端时close()
,java.lang.IllegalStateException: Connection pool shut down
会发生异常。为了避免,setConnectionManagerShared
工作。
CloseableHttpClient:close()
在每次请求后我过去在执行请求时创建了一个新的http客户端实例,最后将其关闭。在这种情况下,最好不要致电close()
。因为,如果连接管理器没有“ shared”标志,它将被关闭,这对于单个请求来说太昂贵了。
实际上,我还在库clj-http中找到了,它根本没有调用Apache HC 4.5上的Clojure包装器close()
。request
在文件core.clj中查看func
乔恩·斯凯特(Jon skeet)说:
该文档对我来说似乎很清楚:“ HttpClient的基本实现也实现了Closeable”-HttpClient是一个接口;CloseableHttpClient是一个抽象类,但是由于它实现了AutoCloseable,因此您可以在try-with-resources语句中使用它。
但是朱尔斯问:
@JonSkeet这很清楚,但是关闭HttpClient实例有多重要?如果很重要,为什么close()方法不属于基本接口?
回答朱尔斯
close不必是基本接口的一部分,因为在每次执行后,基础连接会自动释放回连接管理器
容纳try-with-resources语句。必须实施Closeable。因此将其包含在CloseableHttpClient中。
注意:
不推荐使用AbstractHttpClient中的close方法扩展CloseableHttpClient,我无法找到它的源代码。