有时,需要重复读取HttpEntity,直接使用是行不通的,这时需要使用BufferedHttpEntity类将其进行包装一下。
public static void main(String[] args) throws IOException { CloseableHttpClient httpclient = HttpClients.createDefault(); HttpGet httpget = new HttpGet("http://localhost:9999/index"); CloseableHttpResponse response = httpclient.execute(httpget); try { HttpEntity entity = response.getEntity(); if (entity != null) { System.out.println("==============重复使用response entity================================"); entity = new BufferedHttpEntity(entity); System.out.println(EntityUtils.toString(entity)); System.out.println(EntityUtils.toString(entity)); } } finally { response.close(); } }
其原理也很简单,直接看下源码
(1) 使用了一个byte[] 将entity的内容缓存起来
public BufferedHttpEntity(final HttpEntity entity) throws IOException { super(entity); if (!entity.isRepeatable() || entity.getContentLength() < 0) { final ByteArrayOutputStream out = new ByteArrayOutputStream(); entity.writeTo(out); out.flush(); this.buffer = out.toByteArray(); } else { this.buffer = null; } }
将entity 写到 ByteArrayOutputStream 对象,然后转成byteArray存起来, this.buffer 就是一个byte[]。
(2)读取内容时直接读取缓存byte[]中的内容
而getContent()源码如下:
public InputStream getContent() throws IOException { return this.buffer != null ? new ByteArrayInputStream(this.buffer) : super.getContent(); }
由第一步知,buffer不为null, 所以每次读取内容时,都会创建一个ByteArrayInputStream对象!从而间接的实现了重复使用enity的目的。
日拱一卒无有尽,功不唐捐终入海