在 Apache HttpClient 4.x 中多次读取响应正文
Posted
技术标签:
【中文标题】在 Apache HttpClient 4.x 中多次读取响应正文【英文标题】:Reading from response body multiple times in Apache HttpClient 4.x 【发布时间】:2013-04-19 07:06:05 【问题描述】:我在我的应用程序中使用 Apache HttpClient 4.2.3。我们像这样存储 HTTP 调用的响应:
HttpResponse httpResponse = (DefaultHttpClient)httpClient.execute(httpRequest);
响应正文是 4.x API 中的 InputStream:
InputStream responseStream = httpResponse.getEntity().getContent();
我的问题是我需要在应用程序的各个点将响应正文作为字符串和字节 [] 读取。但是 Apache 使用的 InputStream 是一个 EofSensorInputStream,这意味着一旦我到达流 EOF,它就会关闭。无论如何我可以多次获取字符串和字节[]表示而不关闭流?
我已经尝试过wrapping the byte array in a new ByteArrayInputStream 并将其设置为请求正文,但它不起作用,因为我的响应正文可以达到几场演出。我也试过this,但我注意到原始响应流仍然关闭。
欢迎任何指点。
编辑:在相关说明中,如果我可以在不消耗流或通过反转消耗的情况下找到 InputStream 的长度,那也很棒。
【问题讨论】:
【参考方案1】:1 .我认为您的要求有些矛盾:
一)
它不起作用,因为我的响应正文可以达到几场演出
b)
无论如何我可以多次获取字符串和字节[]表示而不关闭流
如果你没有足够的内存,这是不可能的。
顺便说一句,以字节形式获取响应的另一种方法是EntityUtils.byte[] toByteArray(final HttpEntity entity)
。
你真的需要 N-gigs String 吗?你打算用它做什么?
2 。
如果我能找到 InputStream 的长度也很棒
httpResponse.getEntity().getContentLength()
3 .由于响应不适合内存,我建议将其保存到文件(或临时文件)中。然后在该文件上设置 InputStream,然后根据需要多次读取。
【讨论】:
IOUtils 或 EntityUtils 会给你 byte[],不会因为它们读取整个流,在这种情况下流被关闭(EofSensorInputStream)。这意味着我不能在响应流上再次调用 getAsByteArray(InputStream) 。另外,关于内存问题,我可能有能力在内存中占用一个大字节[],但不能超过这个。 @Karthik.V 从 EntityUtils.toByteArray() 获得 byte[] 后,您将获得所需的数据的单个副本。您也可以将其包装到 ByteArrayInputStream 中,它不应导致 OutOfMemoryError,因为 ByteArrayInputStream 不复制 byte[]。顺便说一句,你不应该保持这么长时间的响应,记住这是来自远程服务器的响应。你打算如何重读它?那会导致服务器再次向您发送 N-gigs 吗?关于如何多次重新阅读大响应,请参阅我的答案中的第 3 项。以上是关于在 Apache HttpClient 4.x 中多次读取响应正文的主要内容,如果未能解决你的问题,请参考以下文章
如何从 Apache HttpClient 4.x 获取 cookie?
Android API 23 - HttpClient 4.X 重新打包