HTTP entity

HTTP messages can carry a content entity associated with the request or response. Entities can be found in some requests and in some responses, as they are optional. Requests that use entities are referred to as entity enclosing requests. The HTTP specification defines two entity enclosing request methods: POST and PUT. Responses are usually expected to enclose a content entity. There are exceptions to this rule such as responses to HEAD method and 204 No Content304 Not Modified205 Reset Content responses.

HttpClient distinguishes three kinds of entities, depending on where their content originates:

  • streamed:  The content is received from a stream, or generated on the fly. In particular, this category includes entities being received from HTTP responses. Streamed entities are generally not repeatable.

  • self-contained:  The content is in memory or obtained by means that are independent from a connection or other entity. Self-contained entities are generally repeatable. This type of entities will be mostly used for entity enclosing HTTP requests.

  • wrapping:  The content is obtained from another entity.

This distinction is important for connection management when streaming out content from an HTTP response. For request entities that are created by an application and only sent using HttpClient, the difference between streamed and self-contained is of little importance. In that case, it is suggested to consider non-repeatable entities as streamed, and those that are repeatable as self-contained.

Repeatable entities

An entity can be repeatable, meaning its content can be read more than once. This is only possible with self contained entities (like ByteArrayEntity or StringEntity)

Using HTTP entities

Since an entity can represent both binary and character content, it has support for character encodings (to support the latter, ie. character content).

The entity is created when executing a request with enclosed content or when the request was successful and the response body is used to send the result back to the client.

To read the content from the entity, one can either retrieve the input stream via the HttpEntity#getContent() method, which returns an java.io.InputStream, or one can supply an output stream to the HttpEntity#writeTo(OutputStream) method, which will return once all content has been written to the given stream.

When the entity has been received with an incoming message, the methods HttpEntity#getContentType() and HttpEntity#getContentLength() methods can be used for reading the common metadata such as Content-Type and Content-Length headers (if they are available). Since the Content-Type header can contain a character encoding for text mime-types like text/plain or text/html, the HttpEntity#getContentEncoding() method is used to read this information. If the headers aren't available, a length of -1 will be returned, and NULL for the content type. If the Content-Type header is available, a Header object will be returned.

When creating an entity for a outgoing message, this meta data has to be supplied by the creator of the entity.

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);

stdout >

Content-Type: text/plain; charset=utf-8
17
important message
17

Ensuring release of low level resources

In order to ensure proper release of system resources one must close either the content stream associated with the entity or the response itself

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();
}

The difference between closing the content stream and closing the response is that the former will attempt to keep the underlying connection alive by consuming the entity content while the latter immediately shuts down and discards the connection.

Please note that the HttpEntity#writeTo(OutputStream) method is also required to ensure proper release of system resources once the entity has been fully written out. If this method obtains an instance of java.io.InputStream by calling HttpEntity#getContent(), it is also expected to close the stream in a finally clause.

When working with streaming entities, one can use the EntityUtils#consume(HttpEntity) method to ensure that the entity content has been fully consumed and the underlying stream has been closed.

There can be situations, however, when only a small portion of the entire response content needs to be retrieved and the performance penalty for consuming the remaining content and making the connection reusable is too high, in which case one can terminate the content stream by closing the response.

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();
}

The connection will not be reused, but all level resources held by it will be correctly deallocated.

Consuming entity content

The recommended way to consume the content of an entity is by using its HttpEntity#getContent() or HttpEntity#writeTo(OutputStream) methods. HttpClient also comes with the EntityUtils class, which exposes several static methods to more easily read the content or information from an entity. Instead of reading the java.io.InputStream directly, one can retrieve the whole content body in a string / byte array by using the methods from this class. However, the use of EntityUtils is strongly discouraged unless the response entities originate from a trusted HTTP server and are known to be of limited length.

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();
}

In some situations it may be necessary to be able to read entity content more than once. In this case entity content must be buffered in some way, either in memory or on disk. The simplest way to accomplish that is by wrapping the original entity with the BufferedHttpEntity class. This will cause the content of the original entity to be read into a in-memory buffer. In all other ways the entity wrapper will be have the original one.

CloseableHttpResponse response = <...>
HttpEntity entity = response.getEntity();
if (entity != null) {
entity = new BufferedHttpEntity(entity);
}

Producing entity content

HttpClient provides several classes that can be used to efficiently stream out content throught HTTP connections. Instances of those classes can be associated with entity enclosing requests such as POST and PUT in order to enclose entity content into outgoing HTTP requests. HttpClient provides several classes for most common data containers such as string, byte array, input stream, and file: StringEntityByteArrayEntityInputStreamEntity, and FileEntity.

File file = new File("somefile.txt");
FileEntity entity = new FileEntity(file, ContentType.create("text/plain", "UTF-8")); HttpPost httppost = new HttpPost("http://localhost/action.do");
httppost.setEntity(entity);

Please note InputStreamEntity is not repeatable, because it can only read from the underlying data stream once. Generally it is recommended to implement a custom HttpEntity class which is self-contained instead of using the generic InputStreamEntityFileEntity can be a good starting point.

HTML forms

Many applications need to simulate the process of submitting an HTML form, for instance, in order to log in to a web application or submit input data. HttpClient provides the entity class UrlEncodedFormEntity to facilitate the process.

List<NameValuePair> formparams = new ArrayList<NameValuePair>();
formparams.add(new BasicNameValuePair("param1", "value1"));
formparams.add(new BasicNameValuePair("param2", "value2"));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, Consts.UTF_8);
HttpPost httppost = new HttpPost("http://localhost/handler.do");
httppost.setEntity(entity);

The UrlEncodedFormEntity instance will use the so called URL encoding to encode parameters and produce the following content:

param1=value1&param2=value2

Content chunking

Generally it is recommended to let HttpClient choose the most appropriate transfer encoding based on the properties of the HTTP message being transferred. It is possible, however, to inform HttpClient that chunk coding is preferred by setting HttpEntity#setChunked() to true. Please note that HttpClient will use this flag as a hint only. This value will be ignored when using HTTP protocol versions that do not support chunk coding, such as HTTP/1.0.

StringEntity entity = new StringEntity("important message", ContentType.create("plain/text", Consts.UTF_8));
entity.setChunked(true);
HttpPost httppost = new HttpPost("http://localhost/acrtion.do");
httppost.setEntity(entity);

HttpClient(4.3.5) - HTTP Entity的更多相关文章

  1. httpclient在获取response的entity时报异常

    httpClient报异常:Premature end of chunk coded message body: closing chunk expected 首先这个异常提示直译过来就是:被编码信息 ...

  2. 使用httpclient 调用selenium webdriver

    结合上次研究的selenium webdriver potocol ,自己写http request调用remote driver代替selenium API selenium web driver ...

  3. HttpClient发送Get和Post请求

    package JanGin.httpClient.demo; import java.io.IOException; import java.io.UnsupportedEncodingExcept ...

  4. HttpClient

    Http协议的重要性相信不用我多说了,HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性(具体区别,日后我们再讨论),它不仅是客户端发送Http请求变得容易,而且 ...

  5. HttpClient请求

    HttpClient HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的.最新的.功能丰富的支持 HTTP 协议的客户端编程工具包, 并且它支持 HTTP ...

  6. 使用HttpClient 发送get、post请求,及其解析xml返回数据

    一.关于HttpClient的使用: 可以参考这个博客地址,这里有详细的介绍,需要的可以先看一下: 地址是:http://blog.csdn.net/wangpeng047/article/detai ...

  7. HttpClient 教程 (A)

    前言 超文本传输协议(HTTP)也许是当今互联网上使用的最重要的协议了.Web服务,有网络功能的设备和网络计算的发展,都持续扩展了HTTP协议的角色,超越了用户使用的Web浏览器范畴,同时,也增加了需 ...

  8. HttpClient模拟http请求

    Http协议的重要性相信不用我多说了,HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性(具体区别,日后我们再讨论),它不仅是客户端发送Http请求变得容易,而且 ...

  9. 接口测试之HttpClient

    HttpClient使用详解   Http协议的重要性相信不用我多说了,HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性(具体区别,日后我们再讨论),它不仅是客 ...

随机推荐

  1. HDU 3666 THE MATRIX PROBLEM (差分约束)

    题意:给定一个最大400*400的矩阵,每次操作可以将某一行或某一列乘上一个数,问能否通过这样的操作使得矩阵内的每个数都在[L,R]的区间内. 析:再把题意说明白一点就是是否存在ai,bj,使得l&l ...

  2. System.getProperties()对应的key/value列表

    Key                     Meaning ——————-     —————————— "file.separator"        File separa ...

  3. MyBatis中井号与美元符号的区别

    #{变量名}可以进行预编译.类型匹配等操作,#{变量名}会转化为jdbc的类型. select * from tablename where id = #{id} 假设id的值为12,其中如果数据库字 ...

  4. C# 生成解决方案失败,点击项目重新生成报找不到命名空间

    1.点击生成解决方案失败,点击项目“重新生成”找不到“XXX”命名空间. 尝试点击"重新生成解决方案"多次,然后点击项目的"重新生成"即可解决.

  5. js奇葩错误 字符串传递问题

    第一种方式function hello(){    var name="he";    var content="<input type=button value= ...

  6. ios8,xcode6 周边

    NSBundle.mainBundle().infoDictionary iOS 8中带按钮的推送代码 ") ){ application.registerForRemoteNotifica ...

  7. cocos2d 制作动态光晕效果基础 —— blendFunc

    转自:http://blog.csdn.net/yang3wei/article/details/7795764 最近的项目要求动态光晕的效果. 何谓动态光晕?之前不知道别人怎么称呼这个效果, 不过在 ...

  8. 微信开发模式(php)

    才開始学习微信开发模式和PHP,在此记录以供后阅. <?php /** * wechat php test */ //define your token define( "TOKEN& ...

  9. delphi array应用 DayOfWeek星期几判断

    //array应用 DayOfWeek星期几判断 procedure TForm1.Button1Click(Sender: TObject);var    days:array[1..7] of s ...

  10. delphi 11 编辑模式 浏览模式

    编辑模式 浏览模式 设置焦点 //在使用前需要Webbrowser已经浏览过一个网页 否则错误 uses MSHTML; ///获取Webbrowser编辑模式里面的内容procedure EditM ...