Apache HttpClient临时错误:NoHttpResponseException

我有一个web服务正在接受与XML的POST方法。 它工作正常,然后在一些随机的场合,它没有通信到服务器抛出IOException消息The target server failed to respond 。 随后的调用工作正常。

大多数情况下,当我打电话,然后离开我的应用程序闲置了10-15分钟。 我之后做的第一个调用返回这个错误。

我试了几件事

我设置了重试处理程序

 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); 

但这个retey从来没有被调用。 (是的,我使用正确的instanceof子句)。 debugging这个类永远不会被调用。

我甚至尝试设置HttpProtocolParams.setUseExpectContinue(httpClient.getParams(), false); 但没用。 有人可以build议我现在可以做什么?

重要除了搞清楚为什么我得到exception,我有一个重要的问题是为什么不在这里工作的重试处理程序?

由连接pipe理器保持活动状态的持久连接最有可能会变陈旧。 也就是说,目标服务器在连接结束时closures连接,而HttpClient不能响应该事件,而连接处于空闲状态,从而导致连接closures或“过时”。 通常这不是问题。 HttpClient采用多种技术来validation连接的有效性。 即使旧的连接检查被禁用,并且一个陈旧的连接被用来传输一个请求消息,这个请求的执行通常会在SocketException的写操作中失败,并且会自动重试。 但是,在某些情况下,写入操作可以在没有exception的情况下终止,并且随后的读取操作返回-1(stream结束)。 在这种情况下,HttpClient没有别的select,只能假定请求成功,但是服务器由于服务器端的意外错误而很可能无法响应。

解决这种情况的最简单的方法是,在闲置一段时间之后,清除闲置时间超过1分钟的过期连接和连接。 有关详细信息,请参阅HttpClient教程的这一部分 。

接受的答案是正确的,但缺乏解决scheme。 为了避免这个错误,你可以像在这个答案中那样为你的HTTP客户端添加setHttpRequestRetryHandler(或者apache组件4.4的setRetryHandler)。