您的位置:首页 > 理论基础 > 计算机网络

【HttpClient4.5中文教程】【第一章 :基础】1.1执行请求(二)

2015-10-29 23:22 453 查看
原文:http://blog.csdn.net/u011179993/article/details/47147909


更多HttpClient4.5中文教程请查看点击打开链接

===========================================================================================================


1.1.4.HTTP实体(HTTP Entity)

HTTP报文能够携带与请求或相应相关联的内容实体。实体存在于某些请求、响应中,它门是可选的。使用实体的请求被称为内含实体请求【译者:原文为entity enclosing requests,我把它翻译为 内含实体请求】。HTTP规范定义了两种内含实体请求,POST和PUT。而响应总是内含实体。但有些响应不符合这一规则,比如,对HEAD方法的响应和状态为204
No Content, 304 Not Modified, 205 Reset Content的响应。

依据实体的内容来源,HttpClient区分出三种实体:

流式实体(streamed):内容来源于一个流,或者在运行中产生【译者:原文为generated on the fly】。特别的,这个类别包括从响应中接收到的实体。流式实体不可重复。

自包含实体(self-contained):在内存中的内容或者通过独立的连接/其他实体获得的内容。自包含实体是可重复的。这类实体大部分是HTTP内含实体请求。

包装实体(wrapping):从另外一个实体中获取内容。


1.1.4.1 可重复实体

一个实体能够被重复,意味着它的内容能够被读取多次。它仅可能是自包含实体(像ByteArrayEntity或StringEntity)


1.1.4.2 使用HTTP实体

由于一个实体能够表现为二进制和字符内容,它支持二进制编码(为了支持后者,即字符内容)。

实体将会在一些情况下被创建:当执行一个含有内容的请求时或者当请求成功,响应体作为结果返回给客户端时。为了读取实体的内容,可以通过HttpEntity#getContent() 方法取出输入流,返回一个java.io.InputStream,或者提供一个输出流给HttpEntity#writeTo(OutputStream) 方法,它将会返回写入给定流的所有内容。

当实体内部含有信息时,使用HttpEntity#getContentType()和HttpEntity#getContentLength()方法将会读取一些基本的元数据,比如Content-Type和Content-Length这样的首部(如果他们可用的话),由于Content-Type首部能够包含文本MIME类型(像 text/plain 或text/html),它也包含了与MIME类型相对应的字符编码,HttpEntity#getContentEncoding()方法被用来读取这些字符编码。如果对应的首部不存在,则Content-Length的返回值为-1,Content-Type返回值为NULL。如果Content-Type是可用的,一个Header类的对象将会返回。

当我们构建一个具有可用信息的实体时,元数据将会被实体构建器提供。【译者:我理解的是,如下面例子中的长度,并没有声明,但是可用,是构建器生成的】

[java] view
plaincopy

StringEntity myEntity = new StringEntity("important message",

ContentType.create("text/plain", "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.5.确保释放低级别的资源

为了确保正确的释放系统资源,你必须关掉与实体与实体相关的的内容流,还必须关掉响应本身。

[java] view
plaincopy

CloseableHttpClient httpclient = HttpClients.createDefault();

HttpGet httpget = new HttpGet("http://localhost/");

CloseableHttpResponse response = httpclient.execute(httpget);

try {

HttpEntity entity = response.getEntity();

if (entity != null) {

InputStream instream = entity.getContent();

try {

// do something useful

} finally {

instream.close();

}

}

} finally {

response.close();

}

关闭内容流和关闭响应的不同点是:前者将会通过消费实体内容保持潜在的连接,而后者迅速的关闭并丢弃连接。

请注意,一旦实体被HttpEntity#writeTo(OutputStream)方法成功地写入时,也需要确保正确地释放系统资源。如果方法获得通过HttpEntity#getContent(),它也需要在一个finally子句中关闭流。

当使用实体时,你可以使用EntityUtils#consume(HttpEntity)方法来确保实体内容完全被消费并且使潜在的流关闭。

某些情况,整个响应内容的仅仅一小部分需要被取出,会使消费其他剩余内容的性能代价和连接可重用性代价太高,这时可以通过关闭响应来终止内容流。【译者:例子中可以看出,实体输入流仅仅读取了两个字节,就关闭了响应,也就是按需读取,而不是读取全部响应】

[java] view
plaincopy

CloseableHttpClient httpclient = HttpClients.createDefault();

HttpGet httpget = new HttpGet("http://localhost/");

CloseableHttpResponse response = httpclient.execute(httpget);

try {

HttpEntity entity = response.getEntity();

if (entity != null) {

InputStream instream = entity.getContent();

int byteOne = instream.read();

int byteTwo = instream.read();

// Do not need the rest

}

} finally {

response.close();

}

这样,连接将不会被重用,它分配的所有级别的资源将会被解除。


1.1.6.消费实体内容

为了消费实体内容,推荐的方式是使用HttpEntity#getContent()或者 HttpEntity#writeTo(OutputStream)方法。HttpClient也提供了一个EntityUtils类,它有几个静态方法更容易的从实体中读取内容或信息。取代了直接读取java.io.InputStream,你可以通过这个类的方法取出全部内容体并放入一个String
中或者byte数组中。可是,强烈不建议使用EntityUtils,除非响应实体来自于信任的HTTP服务器并且知道它的长度。【译者:】

[java] view
plaincopy

CloseableHttpClient httpclient = HttpClients.createDefault();

HttpGet httpget = new HttpGet("http://localhost/");

CloseableHttpResponse response = httpclient.execute(httpget);

try {

HttpEntity entity = response.getEntity();

if (entity != null) {

long len = entity.getContentLength();

if (len != -1 && len < 2048) {

System.out.println(EntityUtils.toString(entity));

} else {

// Stream content out

}

}

} finally {

response.close();

}

在某些情况下,多次读取实体内容是必要的。在这种情况下,实体内容必须以一些方式缓冲,内存或者硬盘中。为了达到这个目的,最简单的方法是把原始的实体用BufferedHttpEntity类包装起来。这将会使原始实体的内容读入一个in-memory缓冲区。所有方式的实体包装都是代表最原始的那个实体。

[java] view
plaincopy

CloseableHttpResponse response = <...>

HttpEntity entity = response.getEntity();

if (entity != null) {

entity = new BufferedHttpEntity(entity);

}

==================总结=====================

1.经过前面两节的学习,你已经掌握HttpClient4.5的基本用法了~赶快去试一下吧~

【HttpClient4.5实训】一.GET请求访问新浪网(非原文教程)点击打开链接
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: