Apache HttpClient Intermediate Error: NoHttpResponseException

I have a web service that accepts a POST method with XML. Then it works fine, in some random case, it cannot contact the server, throwing an IOException with the message The target server failed to respond . Subsequent calls work fine.

This mainly happens when I make a few calls and then leave my application idle for about 10-15 minutes. The first call I make after this returns this error.

I tried a couple of things ...

I configure the retry handler as

 HttpRequestRetryHandler retryHandler = new HttpRequestRetryHandler() { public boolean retryRequest(IOException e, int retryCount, HttpContext httpCtx) { if (retryCount >= 3){ Logger.warn(CALLER, "Maximum tries reached, exception would be thrown to outer block"); return false; } if (e instanceof org.apache.http.NoHttpResponseException){ Logger.warn(CALLER, "No response from server on "+retryCount+" call"); return true; } return false; } }; httpPost.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, retryHandler); 

but this retry was not called. (yes, I am using the correct instanceof clause). When debugging, this class is never called.

I even tried HttpProtocolParams.setUseExpectContinue(httpClient.getParams(), false); up HttpProtocolParams.setUseExpectContinue(httpClient.getParams(), false); but to no avail. Can someone tell me what I can do now?

IMPORTANT In addition to figuring out why I get the exception, one of the important issues I am facing is why the retryhandler does not work here?

+64
May 11 '12 at 21:19
source share
6 answers

Most likely, persistent connections that are supported by the connection manager become obsolete. That is, the target server disconnects the connection at its end, without the HttpClient being able to respond to this event, while the connection is in standby mode, which makes the connection half-closed or "out of date". This is usually not a problem. HttpClient uses several methods to validate a connection when it is leased from a pool. Even if the outdated connection check is turned off and the outdated connection is used to transmit the request message, the query execution usually fails in the write operation using SocketException and automatically returns to it. However, in some circumstances, a write operation may end without exception, and a subsequent read operation returns -1 (end of stream). In this case, HttpClient has no choice but to consider the request successful, but the server was not able to respond most likely due to an unexpected error on the server side.

The easiest way to remedy the situation is to evict expired connections and connections that have been idle for longer than, say, 1 minute from the pool after a period of inactivity. See this section of the HttpClient lesson for more details .

+97
May 15 '12 at 12:34
source

The accepted answer is correct, but there is no solution. To avoid this error, you can add setHttpRequestRetryHandler (or setRetryHandler for Apache 4.4 components) for your HTTP client, for example, in this answer .

+15
Jun 07 '16 at 12:55
source

HttpClient 4.4 suffers from an error in this area related to checking for possibly outdated connections before returning to the requestor. He did not confirm if the connection was deprecated, and this leads to an immediate NoHttpResponseException .

This issue was resolved in HttpClient 4.4.1. See this JIRA and release notes

+6
Dec 12 '17 at 9:48 on
source

Currently, most HTTP connections are considered permanent unless otherwise noted . However, to save server resources, the connection rarely remains open forever, the default connection timeout for many servers is quite short, for example, 5 seconds for Apache httpd 2.2 and higher.

The org.apache.http.NoHttpResponseException error is most likely related to one persistent connection that was closed by the server.

You can set the maximum time to save unused connections in the Apache Http client pool in milliseconds.

With Spring Boot, one way to achieve this:

 public class RestTemplateCustomizers { static public class MaxConnectionTimeCustomizer implements RestTemplateCustomizer { @Override public void customize(RestTemplate restTemplate) { HttpClient httpClient = HttpClientBuilder .create() .setConnectionTimeToLive(1000, TimeUnit.MILLISECONDS) .build(); restTemplate.setRequestFactory( new HttpComponentsClientHttpRequestFactory(httpClient)); } } } // In your service that uses a RestTemplate public MyRestService(RestTemplateBuilder builder ) { restTemplate = builder .customizers(new RestTemplateCustomizers.MaxConnectionTimeCustomizer()) .build(); } 
+3
Dec 16 '17 at 16:48
source

This can happen if disableContentCompression() installed in the pool manager assigned to your HttpClient and the target server is trying to use gzip compression.

+2
Apr 12 '19 at 19:24
source

Same issue for me on apache http client 4.5.5 with default header added

Connection: close

solve the problem of

+1
Apr 13 '18 at 16:07
source



All Articles