我正在研究我们公司开发的应用程序。它使用Apache HttpClient库。在源代码中,它使用HttpClient
类来创建连接到服务器的实例。
我想了解Apache HttpClient,我已经走过了this set of examples。所有示例都使用CloseableHttpClient
而不是HttpClient
。所以我认为CloseableHttpClient
是HttpClient
的扩展版本。如果是这种情况,我有两个问题:
答案 0 :(得分:80)
以下是最简单形式的请求执行过程示例:
CloseableHttpClient httpclient = HttpClients.createDefault(); HttpGet httpget = new HttpGet("http://localhost/"); CloseableHttpResponse response = httpclient.execute(httpget); try { //do something } finally { response.close(); }
HttpClient资源释放:当不再需要实例CloseableHttpClient并且即将超出范围时,必须通过调用CloseableHttpClient #close来关闭与之关联的连接管理器(方法。
CloseableHttpClient httpclient = HttpClients.createDefault(); try { //do something } finally { httpclient.close(); }
请参阅Reference了解基本知识。
@Scadge 从Java 7开始,使用try-with-resources语句可确保在语句结束时关闭每个资源。
try(CloseableHttpClient httpclient = HttpClients.createDefault()){
//do something with httpclient here
}
答案 1 :(得分:14)
有同样的问题。其他答案似乎并没有解决为什么close()真的有必要?此外,Op似乎正在努力找出与HttpClient等人合作的首选方式。
根据Apache:
ConstructorInfo ctor = propertyConditionType.GetConstructor(new[] { typeof(string) });
object instance = ctor.Invoke(new object[] { automationId });
此外,关系如下:
// 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
- ThreadSafe。
CloseableHttpClient
- ThreadSafe但deprecated,请改用DefaultHttpClient
。
HttpClientBuilder
- 不是ThreadSafe,但是会创建ThreadSafeHttpClientBuilder
。
- 用于创建CUSTOM
CloseableHttpClient
。
CloseableHttpClient
- 不是ThreadSafe,但是会创建ThreadSafeHttpClients
。
- 用于创建DEFAULT或MINIMAL
CloseableHttpClient
。
根据Apache的首选方式:
CloseableHttpClient
The example他们在CloseableHttpClient httpclient = HttpClients.createDefault();
子句中提供了httpclient.close()
,并且也使用了finally
。
作为替代方案,mkyong的方式也有点有趣:
ResponseHandler
他没有显示HttpClient client = HttpClientBuilder.create().build();
来电,但我认为这是必要的,因为client.close()
仍然是client
的实例。
答案 2 :(得分:13)
其他答案似乎没有解决为什么close()
真的有必要? * 2
在旧的3.x httpcomponents doc中提到它,这是很久以前的,与4.x HC有很大不同。除了解释是如此简短,以至于没有说出这个底层资源是什么。
我对4.5.2版本的源代码做了一些研究,发现CloseableHttpClient:close()
的实现基本上只关闭了它的连接管理器。
(仅供参考)这就是为什么当您使用共享PoolingClientConnectionManager
并致电客户close()
时,会发生异常java.lang.IllegalStateException: Connection pool shut down
。为了避免,setConnectionManagerShared
有效。
CloseableHttpClient:close()
我曾经在做请求时创建一个新的http客户端实例,最后关闭它。在这种情况下,最好不要拨打close()
。因为,如果连接管理员没有"共享"标志,它将被关闭,这对于单个请求来说太贵了。
事实上,我在库clj-http中找到了一个基于Apache HC 4.5的Clojure包装器,根本不会调用close()
。请参阅文件core.clj
request
答案 3 :(得分:8)
HttpClient
不是一个类,它是一个接口。您不能以您的意思使用它进行开发。
您想要的是一个实现HttpClient
接口的类,即CloseableHttpClient
。
答案 4 :(得分:8)
在库HttpClient
的下一个主要版本中,接口将扩展Closeable
。在此之前,如果不需要与早期的4.x版本(4.0,4.1和4.2)兼容,建议使用CloseableHttpClient
。
答案 5 :(得分:2)
CloseableHttpClient
是httpclient库的基类,是所有实现都使用的基类。其他子类大部分已弃用。
HttpClient
是此类和其他类的接口。
然后,您应该在代码中使用CloseableHttpClient
,并使用HttpClientBuilder
创建它。如果需要包装客户端以添加特定行为,则应使用请求和响应拦截器,而不是使用HttpClient
包装。
这个答案是在httpclient-4.3的背景下给出的。
答案 6 :(得分:0)
Jon skeet说:
文档对我来说似乎很清楚:“ HttpClient的基本实现也实现了Closeable”-HttpClient是一个接口; CloseableHttpClient是一个抽象类,但是由于它实现了AutoCloseable,因此您可以在try-with-resources语句中使用它。
但是朱尔斯接着问:
@JonSkeet这很清楚,但是关闭HttpClient实例有多重要?如果重要的话,为什么close()方法不属于基本接口?
Jules的答案
close不必是基本接口的一部分,因为基础连接 每次执行后都会自动释放回连接管理器
容纳try-with-resources语句。必须实施Closeable。因此将其包含在 CloseableHttpClient 中。
注意:
不建议使用扩展了CloseableHttpClient的AbstractHttpClient中的close方法,我无法找到该源代码。