HttpClient 4.0.1 - how to free a connection?

I have a loop over the URL mapping, for each of which I do the following:

private String doQuery(String url) { HttpGet httpGet = new HttpGet(url); setDefaultHeaders(httpGet); // static method HttpResponse response = httpClient.execute(httpGet); // httpClient instantiated in constructor int rc = response.getStatusLine().getStatusCode(); if (rc != 200) { // some stuff... return; } HttpEntity entity = response.getEntity(); if (entity == null) { // some stuff... return; } // process the entity, get input stream etc } 

The first request is fine, the second is an exception:

Exception in thread "main" java.lang.IllegalStateException: Invalid use of SingleClientConnManager: connection is still highlighted. Be sure to release the connection before distributing another one. in org.apache.http.impl.conn.SingleClientConnManager.getConnection (SingleClientConnManager.java:199) in org.apache.http.impl.conn.SingleClientConnManager $ 1.getConnection (SingleClientConnManager.java:173) ......

This is just a single threaded application. How can I free this connection?

+67
java connection
Jan 23 '11 at 18:35
source share
12 answers

To answer my own question: to release the connection (and any other resources associated with the request), you should close the InputStream returned by HttpEntity:

 InputStream is = entity.getContent(); .... process the input stream .... is.close(); // releases all resources 

From docs

+21
Jan 23 2018-11-11T00:
source

The recommended way, Httpcomponents 4.1, is to close the connection and free up any underlying resources:

 EntityUtils.consume(HttpEntity) 

where HttpEntity is the response object.

+91
Aug 22 '11 at 19:22
source

This seems to work fine:

  if( response.getEntity() != null ) { response.getEntity().consumeContent(); }//if 

And do not forget to consume the object, even if you did not open its contents. For example, you expect the HTTP_OK status from the response and don’t get it, you still have to use the object!

+30
Feb 29 '12 at 11:57
source

Starting with version 4.2, they introduced a much more convenient method that simplifies the release of the connection: HttpRequestBase.releaseConnection ()

+18
Sep 12 '12 at 13:11
source

I am reading a detailed answer that specifically addresses Apache HttpClient 4.0.1. I use this version of HttpClient since it is provided by WAS v8.0, and I need to use the provided HttpClient in Apache Wink v1.1.1, also provided by WAS v8.0, to make some REST calls with NTLM validation on Sharepoint.

To quote Oleg Kalnichevsky on the Apache HttpClient mailing list:

Almost all of this code is not needed. (1) HttpClient will automatically release the underlying connection until the content of the object is consumed until the end of the stream; (2) HttpClient will automatically release the underlying connection for any I / O exception that is thrown when reading the contents of the response. No special processing is required in this case.

In fact, this is sufficient to ensure the proper release of resources:

 HttpResponse rsp = httpclient.execute(target, req); HttpEntity entity = rsp.getEntity(); if (entity != null) { InputStream instream = entity.getContent(); try { // process content } finally { instream.close(); // entity.consumeContent() would also do } } 

That's all.

Source

+12
Apr 10 '15 at 21:28
source

If the response should not be used, the request can be aborted using the following code:

 // Low level resources should be released before initiating a new request HttpEntity entity = response.getEntity(); if (entity != null) { // Do not need the rest httpPost.abort(); } 

Link: http://hc.apache.org/httpcomponents-client-ga/tutorial/html/fundamentals.html#d5e143

Apache HttpClient Version: 4.1.3

+7
May 7 '12 at
source

I have this problem when I use HttpClient in multithreaded envirnoment (Servlets). One servlet still contains the connection, and the other wants to get the connection.

Decision:

version 4.0 use ThreadSafeClientConnManager

version 4.2 use PoolingClientConnectionManager

and install these two setters:

 setDefaultMaxPerRoute setMaxTotal 
+4
Dec 07
source

HTTP HEAD requests must be handled a bit differently because response.getEntity () is NULL. Instead, you should capture the HttpContext passed to HttpClient.execute () and get the connection parameter to close it (anyway in HttpComponents 4.1.X).

 HttpRequest httpRqst = new HttpHead( uri ); HttpContext httpContext = httpFactory.createContext(); HttpResponse httpResp = httpClient.execute( httpRqst, httpContext ); ... // Close when finished HttpEntity entity = httpResp.getEntity(); if( null != entity ) // Handles standard 'GET' case EntityUtils.consume( entity ); else { ConnectionReleaseTrigger conn = (ConnectionReleaseTrigger) httpContext.getAttribute( ExecutionContext.HTTP_CONNECTION ); // Handles 'HEAD' where entity is not returned if( null != conn ) conn.releaseConnection(); } 

HttpComponents 4.2.X added releaseConnection () to the HttpRequestBase to make this easier.

+2
Nov 04 '14 at 21:48
source

I had the same problem and it was solved by closing the answer at the end of the method:

 try { // make the request and get the entity } catch(final Exception e) { // handle the exception } finally { if(response != null) { response.close(); } } 
0
May 05 '15 at
source

I am using HttpClient 4.5.3 using CloseableHttpClient#close for me.

  CloseableHttpResponse response = client.execute(request); try { HttpEntity entity = response.getEntity(); String body = EntityUtils.toString(entity); checkResult(body); EntityUtils.consume(entity); } finally { response.close(); } 
0
Apr 03 '17 at 7:23
source

If you want to reuse the connection, then you must consume the content stream completely after each use as follows:

 EntityUtils.consume(response.getEntity()) 

Note: you need to consume the content stream even if the status code is not 200. The following will not be done the next time you use it:

Exception in thread "main" java.lang.IllegalStateException: Invalid use of SingleClientConnManager: connection is still highlighted. Be sure to release the connection before highlighting another.

If this is a one-time use, then simply closing the connection will free up all resources associated with it.

0
Aug 31 '17 at 12:48 on
source

I highly recommend using a handler to handle the response.

 client.execute(yourRequest,defaultHanler); 

It will automatically release the connection to the consume(HTTPENTITY) method.

Handler example:

 private ResponseHandler<String> defaultHandler = new ResponseHandler<String>() { @Override public String handleResponse(HttpResponse response) throws 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); } } }; 
0
Jan 30 '18 at 7:32
source



All Articles