1

Here is a sample program.

public class Foobar {

     private HttpClient;

     public Foobar(RequestConfig config, PoolingHttpClientConnectionManager, connManager) {
return HttpClients.custom()
                .setDefaultRequestConfig(config)
                .setConnectionManager(connManager)
                .build();
}

public Foobarrr execute() {
HttpPost httpPost = new HttpPost("/blah");
HttpResponse response;
        try {
            response = httpClient.execute(httpPost);
            else if (response.getEntity().getContent() != null && response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
                return mapper.readValue(response.getEntity().getContent(), Foobarrr.class);
            }
        catch(Exception ex){
         throw new RuntimeException(ex);


}

In the above case, the client is created only once but reused. I see another version of code in the internet where the httpClient is closed in try-catch. Isn't that an expensive thing or what is the advantage of this over the above way of doing

public void executeWithPooledUsingHttpClientBuilder() throws Exception {
    try (CloseableHttpClient httpClient = HttpClients.custom()
                                                     .setMaxConnTotal(100)
                                                     .setMaxConnPerRoute(20)
                                                     .build()) {
        final HttpGet httpGet = new HttpGet(GET_URL);
        try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
            EntityUtils.consumeQuietly(response.getEntity());
        }
    }
brain storm
  • 30,124
  • 69
  • 225
  • 393

2 Answers2

1

1. The latest version of code is absolutely fine. It is written as per The try-with-resources Statement

The try-with-resources statement is a try statement that declares one or more resources. A resource is an object that must be closed after the program is finished with it. The try-with-resources statement ensures that each resource is closed at the end of the statement. Any object that implements java.lang.AutoCloseable, which includes all objects which implement java.io.Closeable, can be used as a resource.

2. And this won't cause a performance impact since you are already setting the connection manager

public Foobar(RequestConfig config, PoolingHttpClientConnectionManager connManager) {
return HttpClients.custom()
                .setDefaultRequestConfig(config)
                .setConnectionManager(connManager)
                .build();

your connection manager is going to have a pool of connections. Hence closing and requesting again won't be a problem.

Jeril Kuruvila
  • 17,190
  • 1
  • 20
  • 23
  • 1
    HttpClient is closed in the second example I have showed. Closing httpClient, closes connectionManager too. I know about how autocloseable works – brain storm Nov 25 '19 at 15:19
1

Generally it is highly advisable to close HttpClient instances once they are not longer needed.

One, however, can use HttpClientBuilder#setConnectionManagerShared to inform the builder that it should not wire HttpClient to shut down its connection manager when being closed.

ok2c
  • 26,450
  • 5
  • 63
  • 71
  • this blog got me confusing..it says HttpClient should be create once per lifetime of web app. My application is a web-service, so the client is always needed. https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/ – brain storm Nov 25 '19 at 17:44
  • Then do you want to re-use HttpClient? – ok2c Nov 25 '19 at 22:19
  • yes, if it is going to be a performant constraint as mentioned in that blog – brain storm Nov 25 '19 at 22:57
  • The first rule of Apache HttpClient performance optimization is to re-use HttpClient instances – ok2c Nov 26 '19 at 08:19
  • Please re-read my answer more carefully this time. One _must_ close HttpClient instances once they are no longer used even when re-using the underlying connection pool. It does not mean one should be creating and closing those instances all the time. – ok2c Nov 26 '19 at 19:23