多次读取HttpEntity内容

Posted z-qinfeng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多次读取HttpEntity内容相关的知识,希望对你有一定的参考价值。

有时,需要重复读取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的目的。

 

以上是关于多次读取HttpEntity内容的主要内容,如果未能解决你的问题,请参考以下文章

在后台堆栈中多次防止相同的片段

接口-httpClient

从 XML 声明片段获取 XML 编码:部分内容解析不支持 XmlDeclaration

使用不同的底层文件内容多次读取同一个 Oracle 外部表会引发错误 KUP-05011:文件大小已更改

多次调用片段 onCreateView

防止同一片段多次堆叠 (addToBackStack)