Apache HttpClient Interim Error: NoHttpResponseException

2022-08-31 10:37:07

我有一个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);

但这次重试从未被调用。(是的,我使用的是右实例条款)。调试时,从不调用此类。

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

重要除了弄清楚为什么我会遇到异常之外,我还有一个重要的担忧是为什么重试处理程序不能在这里工作?


答案 1

由连接管理器保持活动状态的持久连接很可能变得陈旧。也就是说,目标服务器在其端关闭连接,而 HttpClient 无法在连接处于空闲状态时对该事件做出反应,从而使连接半关闭或“过时”。通常这不是问题。HttpClient 采用多种技术来验证从池租用连接时的有效性。即使禁用了过时的连接检查,并且使用过时的连接来传输请求消息,请求执行通常在使用 SocketException 的写入操作中失败,并自动重试。但是,在某些情况下,写入操作可以无异常地终止,并且后续读取操作返回 -1(流结束)。在这种情况下,HttpClient别无选择,只能假设请求成功,但服务器无法响应,很可能是由于服务器端的意外错误。

纠正这种情况的最简单方法是将过期的连接和闲置时间超过(例如)在一段时间不活动后从池中逐出超过 1 分钟的连接。有关详细信息,请参阅 HttpClient 教程的此部分


答案 2

接受的答案是正确的,但缺乏解决方案。要避免此错误,您可以为 HTTP 客户端添加 setHttpRequestRetryHandler(或 setRetryHandler for apache components 4.4),如本答案所示。


推荐