使用Apache HttpClient 3.0.1的间歇性不完整响应

时间:2009-07-31 20:27:23

标签: java http httpclient

我对此感到难过,所以我想我会问你们有没有遇到过它,因为HttpClient开发有点像艺术。

我面临的问题是:应用程序正在使用Apache HttpClient Java库与同一公司网络中的服务器进行通信。大部分时间它没有问题,但有时我们会看到由不完整的响应引起的一连串异常:它们都缺少结束标记的最后三个字符,因此客户端的解析器会抱怨。这持续5到10分钟,然后消失。

我无法在本地复制此问题,并且我已验证响应是由服务器完全写入的。客户端使用PostMethod的getResponseBodyAsStream()方法获取响应内容,但只调用一次。也许它需要循环调用此方法,直到它在缓冲响应的罕见情况下变为null?

我会感激任何意见。

编辑:服务器正在编写内容长度标头并正确刷新,并在客户端将数据读入字符串:

//method is a PostMethod, client is a HttpClient
client.executeMethod(hostconfig, method); 

InputStream is = method.getResponseBodyAsStream();
String response = null;

try {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();    
    byte[] buf = new byte[1024];
    int len;

    while ((len = is.read(buf)) > 0) {
        bos.write(buf, 0, len);
    }

    response = new String(bos.toByteArray(), "UTF-8");

} ... // closing try block

2 个答案:

答案 0 :(得分:1)

是否正确设置了服务器的内容长度标头?我不是100%确定Commons-HttpClient是否尊重这些,但它很容易。我想不出你为什么需要反复调用getResponseBodyAsStream。

也可以想象你读取流的代码是错误的假设。也许我们可以看到您如何读取数据以确保您实际上正确读取整个流的片段?一些常见的编码错误可能导致只读取缓冲量(这将导致看似随机的失败)。

除此之外,很难说......我们经常使用Commons HttpClient,没有类似的症状。

答案 1 :(得分:1)

我也一直在面对这个问题。只有在将URL从localhost更改为公共URL后才会出现此问题。

我找到了几个解决方案......

我发现的第一个“解决方案”是在开始阅读过程之前执行Thread.sleep(1000)。我认为这会导致缓冲区在尝试读取之前被填充。 (我知道这没有意义,因为read()声明它会阻塞直到数据可用,但不幸的是,read方法有时会认为它已经比预期更早到达了结尾。这更像是一个丑陋的补丁,所以我一直在寻找......

第二个选项和最好的选项是使用BufferedReader中的方法readLine()。此方法正确实现了读取过程。我还没有阅读readLine的源代码,但我认为我们可以在那里找到解决问题的方法。

问候。