HttpClient响应处理程序始终返回闭合流

时间:2010-06-01 16:33:45

标签: java httpclient handler inputstream

我是Java开发的新手,所以请耐心等待。另外,我希望我不是tl;dr的冠军:)。

我正在使用HttpClient通过Http(duh!)发出请求,并且我已经将它用于一个接收URL作为查询字符串参数的简单servlet。我意识到我的代码可以使用一些重构,所以我决定创建自己的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. 无论如何,这是做正确的方法:)?
  4. 我检查了文档,但在这个问题上找不到任何有用的东西。为了节省一些谷歌搜索,这里是Javadoc,这里是HttpClient tutorial(第1.1.8节 - 响应处理程序)。

    谢谢,
    亚历

2 个答案:

答案 0 :(得分:5)

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

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

在你的情况下,你真的不需要ResponseHandler。

答案 1 :(得分:1)

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

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

如果内容不是很适合,那么你必须自己进行资源管理而不是ResponseHandler。