Java Apache HttpClient API 中的 CloseableHttpClient 和 HttpClient 有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21574478/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the difference between CloseableHttpClient and HttpClient in Apache HttpClient API?
提问by Nayana Adassuriya
I'm studying an application developed by our company. It uses the Apache HttpClient library. In the source code it uses the HttpClient
class to create instances to connect to a server.
我正在研究我们公司开发的应用程序。它使用 Apache HttpClient 库。在源代码中,它使用HttpClient
该类创建实例以连接到服务器。
I want to learn about Apache HttpClient and I've gone trough this set of examples. All the examples use CloseableHttpClient
instead of HttpClient
. So I think CloseableHttpClient
is an extended version of HttpClient
. If this is the case I have two questions:
我想了解 Apache HttpClient 并且我已经浏览了这组示例。所有示例都使用CloseableHttpClient
代替HttpClient
。所以我认为CloseableHttpClient
是HttpClient
. 如果是这种情况,我有两个问题:
- What is the difference between these two?
- Which class is recommended to use for my new development?
- 这两者有什么区别?
- 建议在我的新开发中使用哪个类?
采纳答案by Sagar Pudi
- The main entry point of the HttpClient API is the HttpClient interface.
- The most essential function of HttpClient is to execute HTTP methods.
- Execution of an HTTP method involves one or several HTTP request / HTTP response exchanges, usually handled internally by HttpClient.
- HttpClient API 的主要入口点是 HttpClient 接口。
- HttpClient 最本质的功能是执行 HTTP 方法。
- HTTP 方法的执行涉及一个或多个 HTTP 请求/HTTP 响应交换,通常由 HttpClient 内部处理。
- CloseableHttpClient is an abstract class which is the base implementation of HttpClient that also implements java.io.Closeable.
Here is an example of request execution process in its simplest form:
CloseableHttpClient httpclient = HttpClients.createDefault(); HttpGet httpget = new HttpGet("http://localhost/"); CloseableHttpResponse response = httpclient.execute(httpget); try { //do something } finally { response.close(); }
- CloseableHttpClient 是一个抽象类,它是 HttpClient 的基本实现,它也实现了 java.io.Closeable。
以下是最简单形式的请求执行过程示例:
CloseableHttpClient httpclient = HttpClients.createDefault(); HttpGet httpget = new HttpGet("http://localhost/"); CloseableHttpResponse response = httpclient.execute(httpget); try { //do something } finally { response.close(); }
HttpClient resource deallocation:When an instance CloseableHttpClient is no longer needed and is about to go out of scope the connection manager associated with it must be shut down by calling the CloseableHttpClient#close() method.
CloseableHttpClient httpclient = HttpClients.createDefault(); try { //do something } finally { httpclient.close(); }
HttpClient 资源释放:当不再需要 CloseableHttpClient 实例并且即将超出范围时,必须通过调用 CloseableHttpClient#close() 方法关闭与其关联的连接管理器。
CloseableHttpClient httpclient = HttpClients.createDefault(); try { //do something } finally { httpclient.close(); }
see the Referenceto learn fundamentals.
请参阅参考以了解基础知识。
@Scadge Since Java 7, Use of try-with-resourcesstatement ensures that each resource is closed at the end of the statement. It can be used both for the client and for each response
@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
}
回答by M. Sfakianos
HttpClient
is not a class, it is an interface. You cannot use it for development in the way you mean.
HttpClient
不是一个类,它是一个接口。您不能按照您的意思使用它进行开发。
What you want is a class that implements the HttpClient
interface, and that is CloseableHttpClient
.
你想要的是一个实现HttpClient
接口的类,那就是CloseableHttpClient
.
回答by ok2c
In the next major version of the library HttpClient
interface is going to extend Closeable
. Until then it is recommended to use CloseableHttpClient
if compatibility with earlier 4.x versions (4.0, 4.1 and 4.2) is not required.
在库HttpClient
接口的下一个主要版本中将扩展Closeable
. 在此之前,CloseableHttpClient
如果不需要与早期 4.x 版本(4.0、4.1 和 4.2)兼容,则建议使用。
回答by polve
CloseableHttpClient
is the base class of the httpclient library, the one all implementations use. Other subclasses are for the most part deprecated.
CloseableHttpClient
是 httpclient 库的基类,所有实现都使用它。其他子类在很大程度上已被弃用。
The HttpClient
is an interface for this class and other classes.
该HttpClient
是这个类和其他类的接口。
You should then use the CloseableHttpClient
in your code, and create it using the HttpClientBuilder
. If you need to wrap the client to add specific behaviour you should use request and response interceptors instead of wrapping with the HttpClient
.
然后,您应该CloseableHttpClient
在代码中使用 ,并使用HttpClientBuilder
. 如果您需要包装客户端以添加特定行为,您应该使用请求和响应拦截器,而不是用HttpClient
.
This answer was given in the context of httpclient-4.3.
这个答案是在 httpclient-4.3 的上下文中给出的。
回答by euphoria99
Had the same question. The other answers don't seem to address why close() is really necessary? Also, Op seemed to be struggling to figure out the preferred way to work with HttpClient, et al.
有同样的问题。其他答案似乎没有说明为什么 close() 真的有必要?此外,Op 似乎正在努力找出与 HttpClient 等人一起工作的首选方式。
According to 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.
In addition, the relationships go as follows:
此外,关系如下:
HttpClient
(interface)implemented by:
CloseableHttpClient
- ThreadSafe.
DefaultHttpClient
- ThreadSafe BUT deprecated, useHttpClientBuilder
instead.
HttpClientBuilder
- NOT ThreadSafe, BUT creates ThreadSafeCloseableHttpClient
.
- Use to create CUSTOM
CloseableHttpClient
.
HttpClients
- NOT ThreadSafe, BUT creates ThreadSafeCloseableHttpClient
.
- Use to create DEFAULT or MINIMAL
CloseableHttpClient
.
HttpClient
(界面)实施者:
CloseableHttpClient
- 线程安全。
DefaultHttpClient
- ThreadSafe 但已弃用,请HttpClientBuilder
改用。
HttpClientBuilder
- 不是 ThreadSafe,而是创建 ThreadSafeCloseableHttpClient
。
- 用于创建 CUSTOM
CloseableHttpClient
。
HttpClients
- 不是 ThreadSafe,而是创建 ThreadSafeCloseableHttpClient
。
- 用于创建 DEFAULT 或 MINIMAL
CloseableHttpClient
。
The preferred way according to Apache:
根据Apache的首选方式:
CloseableHttpClient httpclient = HttpClients.createDefault();
The examplethey give does httpclient.close()
in the finally
clause, and also makes use of ResponseHandler
as well.
他们给出的例子httpclient.close()
在finally
从句中使用,也使用了ResponseHandler
。
As an alternative, the way mkyong does it is a bit interesting, as well:
作为替代方案,mkyong 的做法也有点有趣:
HttpClient client = HttpClientBuilder.create().build();
He doesn't show a client.close()
call but I would think it is necessary, since client
is still an instance of CloseableHttpClient
.
他没有显示client.close()
电话,但我认为这是必要的,因为client
它仍然是CloseableHttpClient
.
回答by mzhang
The other answers don't seem to address why close()
is really necessary? * 2
其他答案似乎没有解决为什么close()
真的有必要?* 2
Doubt on the answer "HttpClient resource deallocation".
对答案“HttpClient 资源释放”表示怀疑。
It is mentioned in old 3.x httpcomponents doc, which is long back and has a lot difference from 4.x HC. Besides the explanation is so brief that doesn't say what this underlying resource is.
它在旧的 3.x httpcomponents doc 中有所提及,该文档很早并且与 4.x HC 有很大不同。此外,解释非常简短,没有说明这个底层资源是什么。
I did some research on 4.5.2 release source code, found the implementations of CloseableHttpClient:close()
basically only closes its connection manager.
我对4.5.2 release源码做了一些研究,发现的实现CloseableHttpClient:close()
基本上只是关闭了它的连接管理器。
(FYI) That's why when you use a shared PoolingClientConnectionManager
and call client close()
, exception java.lang.IllegalStateException: Connection pool shut down
will occur. To avoid, setConnectionManagerShared
works.
(仅供参考)这就是为什么当您使用共享PoolingClientConnectionManager
和调用 client 时close()
,java.lang.IllegalStateException: Connection pool shut down
会发生异常。为了避免,setConnectionManagerShared
有效。
I prefer notdo CloseableHttpClient:close()
after every single request
我宁愿不去做CloseableHttpClient:close()
每一个请求后
I used to create a new http client instance when doing request and finally close it. In this case, it'd better not to call close()
. Since, if connection manager doesn't have "shared" flag, it'll be shutdown, which is too expensive for a single request.
我曾经在执行请求时创建一个新的 http 客户端实例并最终关闭它。在这种情况下,最好不要调用close()
。因为,如果连接管理器没有“共享”标志,它将被关闭,这对于单个请求来说太昂贵了。
In fact, I also found in library clj-http, a Clojure wrapper over Apache HC 4.5, doesn't call close()
at all. See func request
in file core.clj
事实上,我还在库clj-http 中发现,Apache HC 4.5 上的 Clojure 包装器根本不调用close()
。参见request
文件core.clj 中的func
回答by Jeril Kuruvila
Jon skeet said:
乔恩·斯基特 说:
The documentation seems pretty clear to me: "Base implementation of HttpClient that also implements Closeable" - HttpClient is an interface; CloseableHttpClient is an abstract class, but because it implements AutoCloseable you can use it in a try-with-resources statement.
文档对我来说似乎很清楚:“也实现了 Closeable 的 HttpClient 的基本实现” - HttpClient 是一个接口;CloseableHttpClient 是一个抽象类,但由于它实现了 AutoCloseable,因此您可以在 try-with-resources 语句中使用它。
But then Jules asked:
但随后朱尔斯问道:
@JonSkeet That much is clear, but how important is it to close HttpClient instances? If it's important, why is the close() method not part of the basic interface?
@JonSkeet 这很清楚,但关闭 HttpClient 实例有多重要?如果它很重要,为什么 close() 方法不是基本接口的一部分?
Answer for Jules
朱尔斯的回答
close need not be part of basic interface since underlying connection is released back to the connection manager automatically after every execute
close 不需要是基本接口的一部分,因为底层连接在每次执行后自动释放回连接管理器
To accommodate the try-with-resources statement. It is mandatory to implement Closeable. Hence included it in CloseableHttpClient.
适应 try-with-resources 语句。强制实现 Closeable。因此将其包含在CloseableHttpClient 中。
Note:
笔记:
close method in AbstractHttpClient which is extending CloseableHttpClient is deprecated, I was not able to find the source code for that.
不推荐使用扩展 CloseableHttpClient 的 AbstractHttpClient 中的 close 方法,我找不到它的源代码。