java HttpClient 响应处理程序总是返回关闭的流
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2951557/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
HttpClient response handler always returns closed stream
提问by Alex Ciminian
I'm new to Java development so please bear with me. Also, I hope I'm not the champion of tl;dr:).
我是 Java 开发的新手,所以请耐心等待。另外,我希望我不是tl;dr的冠军:)。
I'm using HttpClientto make requests over Http (duh!) and I'd gotten it to work for a simple servlet that receives an URL as a query string parameter. I realized that my code could use some refactoring, so I decided to make my own HttpResponseHandler, to clean up the code, make it reusable and improve exception handling.
我正在使用HttpClient通过 Http 发出请求(废话!),并且我让它为一个简单的 servlet 工作,该 servlet 接收一个 URL 作为查询字符串参数。我意识到我的代码可以使用一些重构,所以我决定制作自己的HttpResponseHandler,清理代码,使其可重用并改进异常处理。
I currently have something like this:
我目前有这样的事情:
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;
}
}
And in the method where I make the actual request:
在我提出实际请求的方法中:
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);
}
The problem is that the input stream returned from the handler is closed. I don't have any idea why, but I've checked it with the prints in my code (and no, I haven't used them both at the same time :). While the first print works, the other one gives a closed stream error.
问题是从处理程序返回的输入流是关闭的。我不知道为什么,但我已经用代码中的打印检查了它(不,我没有同时使用它们:)。当第一次打印工作时,另一个打印会出现关闭流错误。
I need InputStreams, because all my other methods expect an InputStreamand not a String. Also, I want to be able to retrieve images (or maybe other types of files), not just text files.
我需要InputStreams,因为我所有的其他方法都需要anInputStream而不是String. 此外,我希望能够检索图像(或其他类型的文件),而不仅仅是文本文件。
I can work around this pretty easily by giving up on the response handler (I have a working implementation that doesn't use it), but I'm pretty curious about the following:
通过放弃响应处理程序(我有一个不使用它的工作实现),我可以很容易地解决这个问题,但我对以下内容很好奇:
- Whydoes it do what it does?
- How do I open the stream, if somethingcloses it?
- What's the right way to do this, anyway :)?
- 为什么它会做它所做的?
- 如果有什么东西关闭了它,我该如何打开它?
- 无论如何,这样做的正确方法是什么:)?
I've checked the docs and I couldn't find anything useful regarding this issue. To save you a bit of Googling, here's the Javadocand here's the HttpClient tutorial(Section 1.1.8 - Response handlers).
我已经检查了文档,但找不到有关此问题的任何有用信息。为了节省您的谷歌搜索,这里是Javadoc,这里是HttpClient 教程(第 1.1.8 节 - 响应处理程序)。
Thanks,
Alex
谢谢,
亚历克斯
回答by ZZ Coder
It closes the stream because ResponseHandler must handle the whole response. Even if you get an open stream, it should be at the end of stream.
它关闭流,因为 ResponseHandler 必须处理整个响应。即使你得到一个开放的流,它也应该在流的末尾。
The stream is closed by BasicHttpEntity's consumeContent() call to ensure you don't read from the stream again.
流由 BasicHttpEntity 的 consumerContent() 调用关闭,以确保您不会再次从流中读取。
In your case, you don't really need ResponseHandler.
在您的情况下,您并不真正需要 ResponseHandler。
回答by Peter Tillemans
The automatic resource management which is called closes the stream for you to make sure all resources are freed and ready for the next task.
被调用的自动资源管理会为您关闭流,以确保所有资源都已释放并为下一个任务做好准备。
If you want streams then you best bet is to copy it to a ByteArray and return a ByteArrayInputStream if the content is relatively modest.
如果您想要流,那么最好的办法是将其复制到 ByteArray 并在内容相对较少时返回 ByteArrayInputStream。
If the content is not modest, then you'll have to do the resource management your self and not the the ResponseHandler.
如果内容不是适度的,那么您将不得不自己进行资源管理,而不是 ResponseHandler。

