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?
- 建议将哪个类用于我的新开发?
6 个解决方案
#1
66
- The main entry point of the HttpClient API is the HttpClient interface.
- HttpClient API的主要入口点是HttpClient接口。
- The most essential function of HttpClient is to execute HTTP methods.
- HttpClient最重要的功能是执行HTTP方法。
- Execution of an HTTP method involves one or several HTTP request / HTTP response exchanges, usually handled internally by HttpClient.
- 执行HTTP方法涉及一个或多个HTTP请求/ HTTP响应交换,通常由HttpClient内部处理。
- CloseableHttpClient is an abstract class which is the base implementation of HttpClient that also implements java.io.Closeable.
- CloseableHttpClient是一个抽象类,它是HttpClient的基本实现,它也实现了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(); }
-
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.
HttpClient资源释放:当不再需要实例CloseableHttpClient并且即将超出范围时,必须通过调用CloseableHttpClient #close()方法关闭与其关联的连接管理器。
CloseableHttpClient httpclient = HttpClients.createDefault(); try { //do something } finally { httpclient.close(); }
see the Reference to learn fundamentals.
请参阅参考资料以了解基础知识。
@Scadge Since Java 7, Use of try-with-resources statement ensures that each resource is closed at the end of the statement.
@Scadge从Java 7开始,使用try-with-resources语句可确保在语句结束时关闭每个资源。
try(CloseableHttpClient httpclient = HttpClients.createDefault()){
//do something with httpclient here
}
#2
11
The other answers don't seem to address why close()
is really necessary? * 2
其他答案似乎没有解决为什么close()真的有必要? * 2
Doubt on the answer "HttpClient resource deallocation".
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版本的源代码做了一些研究,发现了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并调用客户端close()时,异常java.lang.IllegalStateException:将发生连接池关闭。为避免,setConnectionManagerShared工作。
I prefer not do CloseableHttpClient:close()
after every single request
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()。请参阅core.clj文件中的func请求
#3
9
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:
根据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)HttpClient(界面)
implemented by:
实施者:
CloseableHttpClient
- ThreadSafe.CloseableHttpClient - ThreadSafe。
DefaultHttpClient
- ThreadSafe BUT deprecated, useHttpClientBuilder
instead.DefaultHttpClient - 不推荐使用ThreadSafe BUT,而是使用HttpClientBuilder。
HttpClientBuilder
- NOT ThreadSafe, BUT creates ThreadSafeCloseableHttpClient
.HttpClientBuilder - 不是ThreadSafe,但是创建ThreadSafe CloseableHttpClient。
- Use to create CUSTOM
CloseableHttpClient
.- 用于创建CUSTOM CloseableHttpClient。
HttpClients
- NOT ThreadSafe, BUT creates ThreadSafeCloseableHttpClient
.HttpClients - 不是ThreadSafe,但是创建ThreadSafe CloseableHttpClient。
- Use to create DEFAULT or MINIMAL
CloseableHttpClient
.- 用于创建DEFAULT或MINIMAL CloseableHttpClient。
The preferred way according to Apache:
根据Apache的首选方式:
CloseableHttpClient httpclient = HttpClients.createDefault();
The example they give does httpclient.close()
in the finally
clause, and also makes use of ResponseHandler
as well.
他们提供的示例在finally子句中使用了httpclient.close(),并且也使用了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()调用,但我认为这是必要的,因为客户端仍然是CloseableHttpClient的实例。
#4
7
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。在此之前,如果不需要与早期的4.x版本(4.0,4.1和4.2)兼容,建议使用CloseableHttpClient。
#5
6
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。
#6
1
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的上下文中给出的。
#1
66
- The main entry point of the HttpClient API is the HttpClient interface.
- HttpClient API的主要入口点是HttpClient接口。
- The most essential function of HttpClient is to execute HTTP methods.
- HttpClient最重要的功能是执行HTTP方法。
- Execution of an HTTP method involves one or several HTTP request / HTTP response exchanges, usually handled internally by HttpClient.
- 执行HTTP方法涉及一个或多个HTTP请求/ HTTP响应交换,通常由HttpClient内部处理。
- CloseableHttpClient is an abstract class which is the base implementation of HttpClient that also implements java.io.Closeable.
- CloseableHttpClient是一个抽象类,它是HttpClient的基本实现,它也实现了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(); }
-
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.
HttpClient资源释放:当不再需要实例CloseableHttpClient并且即将超出范围时,必须通过调用CloseableHttpClient #close()方法关闭与其关联的连接管理器。
CloseableHttpClient httpclient = HttpClients.createDefault(); try { //do something } finally { httpclient.close(); }
see the Reference to learn fundamentals.
请参阅参考资料以了解基础知识。
@Scadge Since Java 7, Use of try-with-resources statement ensures that each resource is closed at the end of the statement.
@Scadge从Java 7开始,使用try-with-resources语句可确保在语句结束时关闭每个资源。
try(CloseableHttpClient httpclient = HttpClients.createDefault()){
//do something with httpclient here
}
#2
11
The other answers don't seem to address why close()
is really necessary? * 2
其他答案似乎没有解决为什么close()真的有必要? * 2
Doubt on the answer "HttpClient resource deallocation".
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版本的源代码做了一些研究,发现了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并调用客户端close()时,异常java.lang.IllegalStateException:将发生连接池关闭。为避免,setConnectionManagerShared工作。
I prefer not do CloseableHttpClient:close()
after every single request
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()。请参阅core.clj文件中的func请求
#3
9
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:
根据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)HttpClient(界面)
implemented by:
实施者:
CloseableHttpClient
- ThreadSafe.CloseableHttpClient - ThreadSafe。
DefaultHttpClient
- ThreadSafe BUT deprecated, useHttpClientBuilder
instead.DefaultHttpClient - 不推荐使用ThreadSafe BUT,而是使用HttpClientBuilder。
HttpClientBuilder
- NOT ThreadSafe, BUT creates ThreadSafeCloseableHttpClient
.HttpClientBuilder - 不是ThreadSafe,但是创建ThreadSafe CloseableHttpClient。
- Use to create CUSTOM
CloseableHttpClient
.- 用于创建CUSTOM CloseableHttpClient。
HttpClients
- NOT ThreadSafe, BUT creates ThreadSafeCloseableHttpClient
.HttpClients - 不是ThreadSafe,但是创建ThreadSafe CloseableHttpClient。
- Use to create DEFAULT or MINIMAL
CloseableHttpClient
.- 用于创建DEFAULT或MINIMAL CloseableHttpClient。
The preferred way according to Apache:
根据Apache的首选方式:
CloseableHttpClient httpclient = HttpClients.createDefault();
The example they give does httpclient.close()
in the finally
clause, and also makes use of ResponseHandler
as well.
他们提供的示例在finally子句中使用了httpclient.close(),并且也使用了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()调用,但我认为这是必要的,因为客户端仍然是CloseableHttpClient的实例。
#4
7
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。在此之前,如果不需要与早期的4.x版本(4.0,4.1和4.2)兼容,建议使用CloseableHttpClient。
#5
6
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。
#6
1
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的上下文中给出的。