2010-06-01 115 views
1

我是Java开发新手,请耐心等待。另外,我希望我不是tl;dr的冠军:)。HttpClient响应处理程序总是返回关闭流

我使用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. 什么是正确的方式来做到这一点,无论如何:)?

我检查了文档,找不到有关此问题的任何有用信息。为了节省你一些谷歌搜索,这里是Javadoc和这里的HttpClient tutorial(第1.1.8节 - 响应处理程序)。

谢谢,
亚历

回答

4

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

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

就你而言,你并不需要ResponseHandler。

+0

谢谢。我处于一种愤怒的螺旋状中,发现这一切都是有道理的。 – 2012-05-17 16:38:31

+2

你最终做了什么@Alex Ciminian? – 2013-12-26 21:09:21

1

的自动资源管理被称为关闭流为你确保所有的资源被释放,并准备下一个任务。

如果你想要流,那么你最好打赌就是将它复制到一个ByteArray并且如果内容相对适中就返回一个ByteArrayInputStream。

如果内容不够温和,那么您将不得不自己做资源管理而不是ResponseHandler。

+0

你会如何定义'谦虚'? :) – 2010-06-01 16:58:00

+1

取决于机器的并发连接数和内存大小。现在几兆到几十兆的数据可以被认为是“适中的”。 它必须适应内存。 – 2010-06-01 17:08:10