【问题标题】:HttpClient response handler always returns closed streamHttpClient 响应处理程序总是返回关闭的流
【发布时间】:2010-06-01 16:33:44
【问题描述】:

我是 Java 开发新手,所以请多多包涵。还有,我希望我不是tl;dr的冠军:)。

我正在使用HttpClient 通过 Http 发出请求(呃!),我已经让它为一个简单的 servlet 工作,该 servlet 接收一个 URL 作为查询字符串参数。我意识到我的代码可以使用一些重构,所以我决定创建自己的HttpResponseHandler,以清理代码,使其可重用并改进异常处理。

我目前有这样的事情:

public class HttpResponseHandler implements ResponseHandler<InputStream>{

    public InputStream handleResponse(HttpResponse response)
            throws ClientProtocolException, IOException {

        int statusCode = response.getStatusLine().getStatusCode();
        InputStream in = null;

        if (statusCode != HttpStatus.SC_OK) {
            throw new HttpResponseException(statusCode, null);
        } else {
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                in = entity.getContent();
                // This works
                // for (int i;(i = in.read()) >= 0;) System.out.print((char)i); 
            }
        }
        return in;
    }
}

在我提出实际请求的方法中:

HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(target);
ResponseHandler<InputStream> httpResponseHandler = new HttpResponseHandler();
try {
    InputStream in = httpclient.execute(httpget, httpResponseHandler);
    // This doesn't work
    // for (int i;(i = in.read()) >= 0;) System.out.print((char)i);     
    return in;
} catch (HttpResponseException e) {
throw new HttpResponseException(e.getStatusCode(), null);
}

问题是从处理程序返回的输入流是关闭。我不知道为什么,但我已经用我的代码中的打印检查了它(不,我没有同时使用它们:)。虽然第一个打印有效,但另一个给出了关闭的流错误。

我需要InputStreams,因为我所有其他方法都需要InputStream,而不是String。另外,我希望能够检索图像(或者可能是其他类型的文件),而不仅仅是文本文件。

我可以通过放弃响应处理程序来轻松解决这个问题(我有一个不使用它的工作实现),但我对以下内容非常好奇:

  1. 为什么它会做它该做的事?
  2. 如果某事关闭了流,我该如何打开它?
  3. 无论如何,正确的方法是什么:)?

我查看了文档,但找不到任何关于此问题的有用信息。为了节省您在 Google 上搜索的时间,这里是 JavadocHttpClient tutorial(第 1.1.8 节 - 响应处理程序)。

谢谢,
亚历克斯

【问题讨论】:

    标签: java httpclient handler inputstream


    【解决方案1】:

    它关闭流,因为 ResponseHandler 必须处理整个响应。即使你得到一个开放的流,它也应该在流的末尾。

    流由 BasicHttpEntity 的 consumeContent() 调用关闭,以确保您不会再次从流中读取。

    在您的情况下,您实际上并不需要 ResponseHandler。

    【讨论】:

    • 谢谢。我处于愤怒的漩涡中,发现了这一点,这一切都说得通。
    • 你最后做了什么@Alex Ciminian?
    【解决方案2】:

    所谓的自动资源管理会为您关闭流,以确保所有资源都已释放并为下一个任务做好准备。

    如果你想要流,那么最好的办法是将它复制到一个 ByteArray 中,如果内容相对较少,则返回一个 ByteArrayInputStream。

    如果内容不适度,那么您将不得不自己进行资源管理,而不是 ResponseHandler。

    【讨论】:

    • 你如何定义“谦虚”? :)
    • 取决于并发连接数和机器内存大小。如今,几兆字节到十兆字节可以被认为是“适度的”。它必须适合内存。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-24
    • 2022-07-29
    • 2018-05-20
    • 1970-01-01
    • 2022-10-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多