1

I have written a HTTP client, where I am reading the data response from a REST web service. My confusion arises after reading multiple blogs on EntityUtils.consume() and EntiryUtils.toString(). I wanted to know the following:

  1. If EntityUtils.toString(..) ONLY is sufficient as it also closes the stream after reading char bytes. Or I should also do EntityUtils.consume(..) as a good practice.

  2. If both toString() and consume() operation can be used. If yes, then what should be there order.

  3. If I EntityUtils.toString() closes the stream; then why the next call in EntityUtils.consume(..) operations which is entity.isStreaming() still returns true?

Could anyone guide me here to use these operations in a standard way. I am using HTTP version 4+.

I have to use these configurations in multithreaded(web-app) environment.

Thanks

Olaf Kock
  • 46,930
  • 8
  • 59
  • 90
Jaraws
  • 581
  • 1
  • 7
  • 24

1 Answers1

1

I looked at the recommended example from the apache httpclient commons website.

In the example, they used EntityUtils.toString(..) without needing to use EntityUtils.consume(..) before or after.

They mention that calling httpclient.close() ensures all resources are closed.

source: https://hc.apache.org/httpcomponents-client-ga/httpclient/examples/org/apache/http/examples/client/ClientWithResponseHandler.java

CloseableHttpClient httpclient = HttpClients.createDefault();
    try {
        HttpGet httpget = new HttpGet("http://httpbin.org/");

        System.out.println("Executing request " + httpget.getRequestLine());

        // Create a custom response handler
        ResponseHandler<String> responseHandler = new ResponseHandler<String>() {

            @Override
            public String handleResponse(
                    final HttpResponse response) throws ClientProtocolException, IOException {
                int status = response.getStatusLine().getStatusCode();
                if (status >= 200 && status < 300) {
                    HttpEntity entity = response.getEntity();
                    return entity != null ? EntityUtils.toString(entity) : null;
                } else {
                    throw new ClientProtocolException("Unexpected response status: " + status);
                }
            }

        };
        String responseBody = httpclient.execute(httpget, responseHandler);
        System.out.println("----------------------------------------");
        System.out.println(responseBody);
    } finally {
        httpclient.close();
    }

This is what is quoted for the above example:

This example demonstrates how to process HTTP responses using a response handler. This is the recommended way of executing HTTP requests and processing HTTP responses. This approach enables the caller to concentrate on the process of digesting HTTP responses and to delegate the task of system resource deallocation to HttpClient. The use of an HTTP response handler guarantees that the underlying HTTP connection will be released back to the connection manager automatically in all cases.

dulon
  • 735
  • 8
  • 10
  • httpClient.close() would be the last thing to do in a web application where you might be having multiple request accessing same httpClient to make remote calls. But how about the conveyance method httpget.close()? If it is good practice to use it? If I use it , would that be a performance hit?(May be of few milli seconds) – Jaraws Jul 10 '20 at 09:38
  • I am not sure if it is the best way but I actually do construct and close httpclient for every request and performance is acceptable for me (under 1sec). However I do have a shared connection pool for the httpclient which only gets created when the app starts up: final CloseableHttpClient httpclient = HttpClients.custom() .setConnectionManager(poolingHttpClientConnectionManager) .setConnectionManagerShared(true) .setDefaultRequestConfig(defaultRequestConfig).build(); – dulon Jul 21 '20 at 18:15
  • httpClinet gets created when the server starts. But is there a way I can open up the connection too on server startup? Right now connections opens on first request and it takes lot of time establishing route. – Jaraws Jul 28 '20 at 13:34
  • if you use a connection pool, then because connections will be reused, subsequent requests will be faster. If you are concerned about the time for first request - why not make the first request when the server starts up? – dulon Jul 29 '20 at 08:55
  • Even if I do first request on server startup, the same problem will reoccur after the idle connection timeout and then the next request will again take time. – Jaraws Jul 29 '20 at 11:23
  • I believe you can specify in the connection pool to keep the connection alive. See the docs here: https://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html – dulon Jul 29 '20 at 12:00
  • also this answer talks about how connection pool keeping the connection alive: https://stackoverflow.com/a/37535908 – dulon Jul 29 '20 at 14:45