关于Java:Apache HttpClient API中的CloseableHttpClient和HttpClient有什么区别?

What is the difference between CloseableHttpClient and HttpClient in Apache HttpClient API?

我正在研究由我们公司开发的应用程序。 它使用Apache HttpClient库。 在源代码中,它使用HttpClient类创建实例以连接到服务器。

我想了解有关Apache HttpClient的知识,并且已经仔细研究了这组示例。 所有示例都使用CloseableHttpClient而不是HttpClient。 所以我认为CloseableHttpClientHttpClient的扩展版本。 如果是这种情况,我有两个问题:

  • 两者有什么区别?
  • 建议为我的新开发使用哪个课程?


  • HttpClient API的主要入口点是HttpClient接口。
  • HttpClient的最基本功能是执行HTTP方法。
  • HTTP方法的执行涉及一个或多个HTTP请求/ HTTP响应交换,通常由HttpClient在内部处理。
  • CloseableHttpClient是一个抽象类,它是HttpClient的基础实现,它也实现java.io.Closeable。
  • 这是最简单形式的请求执行过程示例:

    1
    2
    3
    4
    5
    6
    7
    8
    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()方法来关闭与其关联的连接管理器。

    1
    2
    3
    4
    5
    6
    CloseableHttpClient httpclient = HttpClients.createDefault();
    try {
        //do something
    } finally {
        httpclient.close();
    }

请参阅参考资料以学习基础知识。

@Scadge
从Java 7开始,使用try-with-resources语句可确保在语句末尾关闭每个资源。

1
2
3
try(CloseableHttpClient httpclient = HttpClients.createDefault()){
//do something with httpclient here
}


有同样的问题。其他答案似乎没有解决为什么close()确实是必要的?而且,Op似乎在努力寻找与HttpClient等一起使用的首选方式。

根据Apache的说法:

1
2
3
4
// 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 (interface)

implemented by:

CloseableHttpClient - ThreadSafe.

DefaultHttpClient - ThreadSafe BUT deprecated, use HttpClientBuilder instead.

HttpClientBuilder-不是ThreadSafe,但会创建ThreadSafe CloseableHttpClient

  • Use to create CUSTOM CloseableHttpClient.

HttpClients-不是ThreadSafe,但会创建ThreadSafe CloseableHttpClient

  • Use to create DEFAULT or MINIMAL CloseableHttpClient.

根据Apache的首选方式:

1
CloseableHttpClient httpclient = HttpClients.createDefault();

他们给出的示例在finally子句中执行httpclient.close(),并且还使用了ResponseHandler

另外,mkyong的执行方式也很有趣:

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

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


其他答案似乎没有解决为什么close()真正必要的原因? * 2

对答案" HttpClient资源释放"有疑问。

在旧的3.x httpcomponents文档中提到了该文档,该文档很早就与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()。请参阅文件core.clj中的func request


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


HttpClient不是类,而是接口。您不能按照您的意思将其用于开发。

您想要的是一个实现HttpClient接口的类,即CloseableHttpClient


CloseableHttpClient是httpclient库的基类,所有实现都使用它。其他子类在大多数情况下已被弃用。

HttpClient是此类和其他类的接口。

然后,您应该在代码中使用CloseableHttpClient,并使用HttpClientBuilder创建它。如果需要包装客户端以添加特定行为,则应使用请求和响应拦截器,而不要包装HttpClient

这个答案是在httpclient-4.3的上下文中给出的。