在Apache HttpClient API中,ClosebleHttpClient和HttpClient之间有什么区别?

tjrkku2a  于 2022-11-16  发布在  Apache
关注(0)|答案(8)|浏览(295)

我正在研究我们公司开发的一个应用程序,它使用Apache HttpClient库,在源代码中使用HttpClient类创建示例来连接服务器。
我想学习Apache HttpClient,我已经学习了this set of examples。所有的例子都使用CloseableHttpClient而不是HttpClient。所以我认为CloseableHttpClientHttpClient的扩展版本。如果是这样的话,我有两个问题:

  • 这两者之间有什么区别?
  • 我的新开发建议使用哪个类?
vfh0ocws

vfh0ocws1#

  • HttpClient API的主要入口点是HttpClient接口。
  • HttpClient最基本的功能是执行HTTP方法。
  • HTTP方法的执行涉及一个或多个HTTP请求/ HTTP响应交换,通常由HttpClient内部处理。
  • ClosebleHttpClient是一个抽象类,它是HttpClient的基本实现,也实现了java. io. Closeble。
  • 下面是一个请求执行过程的最简单形式的示例:
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpget = new HttpGet("http://localhost/");
CloseableHttpResponse response = httpclient.execute(httpget);
try {
    //do something
} finally {
    response.close();
}

***HttpClient资源解除配置:**当不再需要ClosebleHttpClient执行严修,而且即将超出范围时,必须呼叫ClosebleHttpClient #close()方法,关闭与之相关的连接管理员。

CloseableHttpClient httpclient = HttpClients.createDefault();
try {
    //do something
} finally {
    httpclient.close();
}

请参阅Reference以了解基础知识。
@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
}
h43kikqp

h43kikqp2#

我也有同样的问题。其他的答案似乎并没有说明为什么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-执行绪安全,但是deprecated,请改用HttpClientBuilder
HttpClientBuilder-不是线程安全,但创建线程安全CloseableHttpClient

  • 用于创建自定义CloseableHttpClient

HttpClients-不是线程安全,但创建线程安全CloseableHttpClient

  • 用于建立DEFAULT或MINIMAL CloseableHttpClient

根据Apache的首选方式:

CloseableHttpClient httpclient = HttpClients.createDefault();

他们给予的The examplefinally子句中执行httpclient.close(),并且还使用了ResponseHandler
作为一种替代,mkyong的做法也有点有趣:

HttpClient client = HttpClientBuilder.create().build();

他没有显示client.close()调用,但我认为这是必要的,因为client仍然是CloseableHttpClient的一个示例。

jhiyze9q

jhiyze9q3#

其他答案似乎没有说明为什么close()是真正必要的?* 2

对答案“HttpClient资源解除分配”表示怀疑。

它在旧的3.x httpcomponents doc中提到,这是很久以前的事了,与4.x HC有很大的不同。
我对4.5.2版本的源代码做了一些研究,发现CloseableHttpClient:close()的实现基本上只关闭了它的连接管理器。
(FYI)这就是为什么当你使用一个共享的PoolingClientConnectionManager并调用客户端close()时,会发生异常java.lang.IllegalStateException: Connection pool shut down

我更喜欢 * 不 * 在每次请求后执行CloseableHttpClient:close()

我过去常常在请求时创建一个新的http客户端示例,最后关闭它。在这种情况下,最好不要调用close()。因为,如果连接管理器没有“shared”标志,它将被关闭,这对于单个请求来说太昂贵了。
事实上,我还在库clj-http中发现,Apache HC 4.5上的Clojure Package 器根本不调用close()

qjp7pelc

qjp7pelc4#

HttpClient不是一个类,它是一个接口,你不能按照你的意思用它来开发。
您需要的是一个实现HttpClient接口的类,即CloseableHttpClient

8aqjt8rx

8aqjt8rx5#

在库的下一个主要版本中,HttpClient接口将扩展Closeable。在此之前,如果不需要与早期的4.x版本(4.0、4.1和4.2)兼容,建议使用CloseableHttpClient

bttbmeg0

bttbmeg06#

CloseableHttpClient是httpclient库的基类,所有实现都使用它。其他子类大部分都不赞成使用。
HttpClient是这个类别和其他类别的界面。
然后,您应该在代码中使用CloseableHttpClient,并使用HttpClientBuilder创建它。如果您需要 Package 客户端以添加特定行为,您应该使用请求和响应拦截器,而不是使用HttpClient Package 。
这个答案在httpclient-4.3的上下文中给出。

yyhrrdl8

yyhrrdl87#

"乔恩·斯基特说"
文档在我看来非常清楚:“也实现Closeable的HttpClient的基本实现”- HttpClient是一个接口; ClosebleHttpClient是一个抽象类,但由于它实现了AutoCloseable,因此您可以在try-with-resources语句中使用它。
"但朱尔斯问“
@JonSkeet这是很清楚的,但是关闭HttpClient示例有多重要呢?如果它很重要,为什么close()方法不是基本接口的一部分呢?
“茱尔斯的答案"
close不需要是基本接口的一部分,因为在每次执行后,基础连接会自动释放回连接管理器
为了适应try-with-resources语句。必须实现Closeable。因此将其包含在ClosebleHttpClient中。
注意事项:
在AbstractHttpClient中扩展ClosebleHttpClient的close方法被弃用,我无法找到它的源代码。

k97glaaz

k97glaaz8#

您可以像这样放置 * 可关闭项 *

final String uri = "http://localhost:8080/*****";
HttpGet httpGet = new HttpGet(uri);
try (final CloseableHttpClient httpClient = HttpClients.createDefault();
     final CloseableHttpResponse response = httpClient.execute(httpGet)) {
    final String result = EntityUtils.toString(response.getEntity());
    ...
} catch (Exception e) {
    ....
}

相关问题