HTTP实体

HTTP报文可以包含与请求或应答相关的内容实体。部分请求和应答包含实体,因为实体是可选的。HTTP标准定义了两种带实体的方法:POST和PUT。通常应答都包含实体,但是也有一些例外,例如对HEAD请求的应答,204 No Content, 304 Not Modified, 205 Reset Content应答,都不包含实体。

HttpCore有三种不同的实体,取决于内容的来源:

  • 数据流:内容来自数据流,或者在运行过程中产生。特别的是,这个类别包括通过连接接收到的实体。数据流实体通常无法重复。
  • 自我包含:内容在内存中,或者通过不需要连接或其他实体的方式获得。自我包含的实体通常可以重复。
  • 打包:内容来自其他实体

1.1.3.1 可重复的实体

实体可重复,意思是它的内容可以多次读取。只有自我包含的实体可以重复,例如ByteArrayEntityStringEntity

1.1.3.2 使用HTTP实体

HTTP实体可以表示二进制或字符内容,支持字符编码来实现字符内容。

HTTP实体在执行一个带有内容的请求时被创建,或在请求成功后应答报文需要将请求结果发回给客户端时创建。
为了读取实体的内容,我们可以通过HttpEntity#getContent()方法从输入数据流中读取,该方法返回一个java.io.InputStream实例,也可以通过给HttpEntity#writeTo(OutputStream)方法提供一个output stream,这个方法会在所有内容写入output stream后返回。注意,某些非数据流(自我包含)的实体可能无法将内容表示为一个java.io.InputStream。对于这样的实体,只实现HttpEntity#writeTo(OutputStream)方法而在HttpEntity#getContent()抛出UnsupportedOperationException异常是合法的。

EntityUtils类提供几个静态方法来简化从实体中提取内容或信息,可以直接使用这个类的方法来以字符串或字节数组的形式获取整个内容,而不是通过java.io.InputStream读取。

当HTTP实体随着HTTP报文一同被接受时,HttpEntity#getContentType()HttpEntity#getContentLength()方法可以用来读取元数据,例如Content-TypeContent-Length报文头(如果存在)。Content-Type报文头包含一个表示文本mime类型的字符编码,例如text/plaintext/htmlHttpEntity#getContentEncoding()可以用于读取这一信息。如果这些报文头不存在,长度会返回-1,内容类型返回NULL。如果Content-Type报文头存在,则返回Header对象。

在为发出的HTTP报文创建实体时,实体创建者必须提供这些元数据。

StringEntity myEntity = new StringEntity("important message", Consts.UTF_8);

System.out.println(myEntity.getContentType());
System.out.println(myEntity.getContentLength());
System.out.println(EntityUtils.toString(myEntity));
System.out.println(EntityUtils.toByteArray(myEntity).length);
Content-Type: text/plain; charset=UTF-8
17
important message
17

1.1.3.3 确保释放系统资源

为了确保释放系统资源,必须关闭与HTTP实体相关的内容数据流。

HttpResponse response;
HttpEntity entity = response.getEntity();
if (entity != null) {
    InputStream instream = entity.getContent();
    try {
        // do something useful
    } finally {
        instream.close();
    }
}

在使用数据流实体时,可以使用EntityUtils#consume(HttpEntity)方法来确保实体内容被完全消费,以及数据流被关闭。

results matching ""

    No results matching ""