1

I am trying to understand the best way to use apaches HTTPPooledConnectionManager and the Closeable HTTPClient. All examples I have seen seem to create a new HTTPClient in the request and no closing of the HttpClient.
Shouldnt it be static or per class? If HttpClient with pooled connection manager can be reused and the connections are released back to the pool, arent we creating HttpClient everytime we make a request? I would like to especially understand this in a spring based framework.

Here is an example code where I think HttpClient should be static.

import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;

import java.io.IOException;
import java.net.URISyntaxException;

public class Stub2000  {

private CloseableHttpClient httpClient;

public void init()  {

    RequestConfig config = RequestConfig.custom()
            .setConnectTimeout(10000)
            .setSocketTimeout(10000)
            .setConnectionRequestTimeout(10000)
            .build();

    PoolingHttpClientConnectionManager poolManager = new PoolingHttpClientConnectionManager();
    poolManager.setMaxTotal(10);
    poolManager.setDefaultMaxPerRoute(10);
    httpClient = HttpClients
            .custom()
            .setDefaultRequestConfig(config)
            .setConnectionManager(poolManager)
            .build();
}

public void getInfo() throws URISyntaxException, IOException {
    final URIBuilder ruribuilder = new URIBuilder();
    final HttpGet get = new HttpGet();
    ruribuilder.setHost(host)
            .setScheme("https")
            .setPort(5555)
            .setPath(uri)
            .addParameter("txn",txn);

    get.setURI(ruribuilder.build());

    CloseableHttpResponse response = httpClient.execute(get);

    try {

        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode == 200) {
            String result = EntityUtils.toString(response.getEntity());

        }
        else {
            //Some Error
        }
    }catch(Exception e){
        e.printStackTrace();
    } finally {
        EntityUtils.consume(response.getEntity());
    }

}

Everytime a request is made, we create a new HTTPclient of pool size 10 ? If this is a bean initialized with spring framework , and init method was invoked at the time of bean initialization, would it be done only once when the spring initializes or whenever a request is made?

Roma
  • 333
  • 3
  • 11

1 Answers1

2

Shouldnt it be static or per class?

  • For better performance it is better to reuse the client. The way how you will reuse - make it static or create a Bean which will be injected - is up to you. Sometimes you might need several different clients with different configuration i.e. timeouts, etc.

If HttpClient with pooled connection manager can be reused and the connections are released back to the pool, arent we creating HttpClient everytime we make a request?

  • Connection Manager can be reused, this is configurable.

Everytime a request is made, we create a new HTTPclient of pool size 10 ?

  • With default configuration - yes.

If this is a bean initialized with spring framework , and init method was invoked at the time of bean initialization, would it be done only once when the spring initializes or whenever a request is made?

  • It depends not only on bean to be created once, but also on configuration of http client and connection manager

Please refer to Spring RestTemplate - Need to release connection? , http://www.baeldung.com/spring-scheduled-tasks

GiorgosDev
  • 1,757
  • 1
  • 14
  • 16
  • from what I understood from your answer was if its spring managed as would be, there is no need as long as we consume the response entity even if we are creating new httpclients for every request and Spring would take care of closing when it goes out of scope. Also why the link for baeldung.com? do you suggest that we periodically check for unused clients and shut them down ? – Roma Jun 08 '18 at 14:02
  • Not exactly, Spring doesn't manage to for http-client to close connection, it is managed in connection manager. If you'll create new http client per each request together with new connection manager - it is much more expensive than to use one http client. Http clients doesn't need to be shut down, nor closed, http connection should be - in your case HttpGet, you should call releaseConnection() after request is performed. – GiorgosDev Jun 08 '18 at 14:19
  • wouldnt EntityUtils.consume release the connections and close the resources? – Roma Jun 08 '18 at 17:34
  • I am a bit confused now on how the spring framework would initialize this bean. would it create a new bean for every request ( thats what I think ) and destroy the bean? – Roma Jun 08 '18 at 17:34