3

我对此感到困惑,所以我想我会问一下,以防你们中的任何人遇到它,因为 HttpClient 开发有点像一门艺术。

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

我无法在本地复制此问题,并且我已验证响应完全由服务器编写。客户端通过 PostMethod 的 getResponseBodyAsStream() 方法获取响应内容,但只调用了一次。也许它需要循环调用此方法,直到它在响应被缓冲的极少数情况下为空?

我会很感激任何意见。

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

//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
4

2 回答 2

1

我也一直面临这个问题。此问题仅在将 URL 从 localhost 更改为公共 URL 后出现。

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

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

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

问候。

于 2009-10-30T00:58:29.403 回答
1

服务器的内容长度标头是否设置正确?我不是 100% 确定 Commons-HttpClient 是否尊重这些,但它很容易做到。我想不出您需要反复调用 getResponseBodyAsStream 的任何原因。

也可以想象,您用于读取流的代码正在做出错误的假设。也许我们可以看到您如何读取数据的片段,以确保您实际上正确读取了整个流?那里的一些常见编码错误可能导致只能读取缓冲量(这将导致看似随机的故障)。

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

于 2009-07-31T20:34:10.890 回答