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

162,870

Solution 1

  • 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.

  • 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();
    }

  • 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();
    }

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. It can be used both for the client and for each response

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
}

Solution 2

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.


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, use HttpClientBuilder instead.

HttpClientBuilder - NOT ThreadSafe, BUT creates ThreadSafe CloseableHttpClient.

  • Use to create CUSTOM CloseableHttpClient.

HttpClients - NOT ThreadSafe, BUT creates ThreadSafe CloseableHttpClient.

  • Use to create DEFAULT or MINIMAL CloseableHttpClient.

The preferred way according to Apache:

CloseableHttpClient httpclient = HttpClients.createDefault();

The example they give does httpclient.close() in the finally clause, and also makes use of ResponseHandler as well.


As an alternative, the way mkyong does it is a bit interesting, as well:

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.

Solution 3

The other answers don't seem to address why close() is really necessary? * 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.

I did some research on 4.5.2 release source code, found the implementations of CloseableHttpClient:close() basically only closes its connection manager.

(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.

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.

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

Solution 4

HttpClient is not a class, it is an interface. You cannot use it for development in the way you mean.

What you want is a class that implements the HttpClient interface, and that is CloseableHttpClient.

Solution 5

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.

Share:
162,870

Related videos on Youtube

Nayana Adassuriya
Author by

Nayana Adassuriya

Updated on March 13, 2020

Comments

  • Nayana Adassuriya
    Nayana Adassuriya about 4 years

    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.

    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:

    • What is the difference between these two?
    • Which class is recommended to use for my new development?
    • Jon Skeet
      Jon Skeet over 10 years
      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.
    • Jules
      Jules about 10 years
      @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?
    • Jon Skeet
      Jon Skeet about 10 years
      @Jules: I'm afraid I don't know enough about HttpClient to answer that :(
    • Jeril Kuruvila
      Jeril Kuruvila over 4 years
      close need not be part of basic interface since underlying connection is released back to the connection manager automatically
  • gilbertpilz
    gilbertpilz almost 9 years
    This answer sort of begs the question. What does calling close() on an HttpClient cause to happen that wouldn't otherwise happen? Do you leak connections if you don't call close() at the appropriate times/places? Does calling close() prematurely affect your performance by causing you to reconnect when you really didn't need to?
  • Deadron
    Deadron over 7 years
    I looked through the code in httpclient for the answer to this question. The answer is that the close method is used to close internal state. Some of the implementations of HTTPClient(in the httpclient lib) can be configured to use persistent resources such as PooledHttpClientConnectionManager for pooled connections and without such a method you could not clean up these resources if needed.
  • Kasun Siyambalapitiya
    Kasun Siyambalapitiya over 7 years
    @SugarPudi in the above example, do we need to close httpget also
  • zyfo2
    zyfo2 over 6 years
    Could you clarify why it's better than use setConnectionManagerShared and call close() after every request?
  • illcar
    illcar over 6 years
    How are we able to invoke methods on abstract class (CloseableHttpClient) here? Should we not create a concrete subclass first?
  • Sagar Pudi
    Sagar Pudi over 6 years
    @illcar Please go throuth this answer to understand the concept stackoverflow.com/a/4321402/2830834
  • Christophe Roussy
    Christophe Roussy over 6 years
    If you have set a connection pool it will close it ! Once close you would have to create a new instance each time ... Also see hc.apache.org/httpcomponents-client-ga/tutorial/html/…
  • jamie
    jamie over 5 years
    The main benefit, IMHO, is that the execute methods return CloseableHttpResponse instances, rather than HttpReponses. Use the try-with-resources for the execute calls to ensure that the connections are returned to the connection pool.
  • chill appreciator
    chill appreciator over 4 years
    What about HttpGet object? Do we need to close it?
  • Vivek Chavda
    Vivek Chavda about 4 years
    This still doesn't seem to answer "how important is it to close HttpClient instances?"
  • Jaraws
    Jaraws almost 4 years
    What if there is an exception and in that case closable response object will be null? How do we release the connection is such a scenario if I am not using try with resources? As I can not call response.close() now. Thanks
  • Hakanai
    Hakanai over 2 years
    History says that you were wrong, because here we are in v5.1 and HttpClient still does not extend Closeable hc.apache.org/httpcomponents-client-5.1.x/current/httpclient‌​5/…
  • Hakanai
    Hakanai over 2 years
    This answer implies that you don't have to close HttpClient instances at all, which in turn implies that CloseableHttpClient was simply a mistake.
  • Hakanai
    Hakanai over 2 years
    I guess the summary here is that the Apache HTTP Client developers don't know how to make a good API. A good API would decide whether cleaning up resources is important or not. If it were important, then HttpClient would extend Closeable. If it were not important, then HttpClient would not extend Closeable and CloseableHttpClient would not exist. I assume they are just unable to decide which direction to go in.
  • SirHawrk
    SirHawrk almost 2 years
    HttpClientBuilder.create().build(); is what HttpClients.createDefault(); uses under the hood, so there shouldn't be a difference.