有時,需要重復讀取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的目的。