目录:
HTTP报文可以携带和请求或响应相关的内容实体。实体可以在一些请求和响应中找到,因为它们也是可选的。使用了实体的请求被称为封闭实体请求。HTTP规范定义了两种封闭实体的方法:POST和PUT。响应通常期望包含一个内容实体。这个规则也有特例,比如HEAD方法的响应和204 NoContent,304 Not Modified和205 Reset Content响应。
HttpClient根据其内容出自何处区分三种类型的实体:
streamed流式 内容从流中获得,或者在运行中产生。特别是这种分类包含从HTTP响应中获取的实体。流式实体是不可重复生成的。 self-contained自我包含式 内容在内存中或通过独立的连接或其它实体中获得。自我包含式的实体是可以重复生成的。这种类型的实体会经常用于封闭HTTP请求的实体。 wrapping包装式 内容从另外一个实体中获得。 |
当从一个HTTP响应中获取流式内容时,这个区别对于连接管理很重要。对于由应用程序创建而且只使用HttpClient发送的请求实体,流式和自我包含式的不同就不那么重要了。这种情况下,建议考虑如流式这种不能重复的实体,和可以重复的自我包含式实体。
重复实体
实体可以重复,意味着它的内容可以被多次读取。这就仅仅是自我包含式的实体了(像ByteArrayEntity或StringEntity)。
使用HTTP实体
一个实体既可以代表二进制内容又可以代表字符内容,同时也支持字符编码。实体是在使用封闭内容执行请求,或当请求已经成功执行,或当响应体结果发送到客户端时创建的。
要从实体中读取内容,可以通过HttpEntity#getContent()方法从输入流中获取,这会返回一个java.io.InputStream对象,或者提供一个输出流到HttpEntity#writeTo(OutputStream)方法中,这会一次返回所有写入到给定流中的内容。
当实体通过一个收到的报文获取时,HttpEntity#getContentType()方法和 HttpEntity#getContentLength()方法可以用来读取通用的元数据,如Content-Type和Content-Length头部信息(如果它们是可用的)。因为头部信息Content-Type可以包含对文本MIME类型的字符编码,比如text/plain或text /html,HttpEntity#getContentEncoding()方法用来读取这个信息。如果头部信息不可用,那么就返回长度-1,而对于内容类型返回NULL。如果头部信息Content-Type是可用的,那么就会返回一个Header对象。
StringEntity entity =new StringEntity("important message","UTF-8"); System.out.println(entity.getContentType()); System.out.println(entity.getContentLength()); System.out.println(ContentType.getOrDefault(entity)); System.out.println(EntityUtils.toString(entity)); System.out.println(EntityUtils.toByteArray(entity).length); |
输出: |
Content-Type: text/plain; charset=UTF-8 17 text/plain; charset=UTF-8 important message 17 |
确保低级别资源释放
当完成一个响应实体,那么保证所有实体内容已经被完全消耗是很重要的,所以连接可以安全的放回到连接池中,而且可以通过连接管理器对后续的请求重用连接。处理这个操作的最方便的方法是调用HttpEntity#consumeContent()方法来消耗流中的任意可用内容。HttpClient探测到内容流尾部已经到达后,会立即会自动释放低层连接,并放回到连接管理器。HttpEntity#consumeContent()方法调用多次也是安全的。
也可能会有特殊情况,当整个响应内容的一小部分需要获取,消耗剩余内容而损失性能,还有重用连接的代价太高,则可以仅仅通过调用HttpUriRequest#abort()方法来中止请求。
HttpGet httpGet =new HttpGet("http://www.baidu.com"); HttpResponse response = client.execute(httpGet); HttpEntity entity = response.getEntity(); if (entity !=null) { InputStream instream = entity.getContent(); int byteOne = instream.read(); int byteTwo = instream.read(); // Do not need the rest httpGet.abort(); } |
连接不会被重用,但是由它持有的所有级别的资源将会被正确释放。
消耗实体内容
推荐消耗实体内容的方式是使用它的HttpEntity#getContent()或HttpEntity#writeTo(OutputStream)方法。HttpClient也自带EntityUtils类,这会暴露出一些静态方法,这些方法可以更加容易地从实体中读取内容或信息。代替直接读取 java.io.InputStream,也可以使用这个类中的方法以字符串/字节数组的形式获取整个内容体。然而,EntityUtils的使用是强烈不鼓励的,除非响应实体源自可靠的HTTP服务器和已知的长度限制。
HttpGet httpGet =new HttpGet("http://localhost/"); HttpResponse response = client.execute(httpGet); 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 } } |
在一些情况下可能会不止一次的读取实体。此时实体内容必须以某种方式在内存或磁盘上被缓冲起来。最简单的方法是通过使用BufferedHttpEntity类来包装源实体完成。这会引起源实体内容被读取到内存的缓冲区中。在其它所有方式中,实体包装器将会得到源实体。
HttpGet httpGet =new HttpGet("http://localhost/"); HttpResponse response = client.execute(httpGet); HttpEntity entity = response.getEntity(); if (entity !=null) { entity = new BufferedHttpEntity(entity); } |
生成实体内容
HttpClient提供一些类,它们可以用于生成通过HTTP连接获得内容的有效输出流。为了封闭实体从HTTP请求中获得的输出内容,那些类的实例可以和封闭如POST和PUT请求的实体相关联。HttpClient为很多公用的数据容器,比如字符串,字节数组,输入流和文件提供了一些类:StringEntity,ByteArrayEntity,InputStreamEntity和FileEntity。
File file =new File("somefile.txt"); ContentType contentType = ContentType.create("text/plain","UTF-8"); FileEntity entity =new FileEntity(file, contentType); HttpPost httpPost =new HttpPost("http://localhost/action.do"); httpPost.setEntity(entity); |
请注意InputStreamEntity是不可重复的,因为它仅仅能从低层数据流中读取一次内容。通常来说,我们推荐实现一个定制的HttpEntity类,这是自我包含式的,用来代替使用通用的InputStreamEntity。FileEntity也是一个很好的起点。
动态内容实体
通常来说,HTTP实体需要基于特定的执行上下文来动态地生成。通过使用EntityTemplate实体类和ContentProducer接口,HttpClient提供了动态实体的支持。内容生成器是按照需求生成它们内容的对象,将它们写入到一个输出流中。它们是每次被请求时来生成内容。所以用EntityTemplate创建的实体通常是自我包含而且可以重复的。
ContentProducer cp =new ContentProducer() { public void writeTo(OutputStream outstream) throws IOException { Writer writer = new OutputStreamWriter(outstream,"UTF-8"); writer.write("<response>"); writer.write(" <content>"); writer.write(" important stuff"); writer.write(" </content>"); writer.write("</response>"); writer.flush(); } }; HttpEntity entity =new EntityTemplate(cp); HttpPost httppost =new HttpPost("http://localhost/handler.do"); httppost.setEntity(entity); |
HTML表单
许多应用程序需要频繁模拟提交一个HTML表单的过程,比如,为了来记录一个Web应用程序或提交输出数据。HttpClient提供了特殊的实体类UrlEncodedFormEntity来这个满足过程。
List<NameValuePair> fromParams =new ArrayList<NameValuePair>(); fromParams.add(new BasicNameValuePair("param1","value1")); fromParams.add(new BasicNameValuePair("param2","中文参数值")); UrlEncodedFormEntity entity =new UrlEncodedFormEntity(fromParams,"UTF-8"); HttpPost httpPost =new HttpPost("http://localhost/handler.do"); httpPost.setEntity(entity); |
UrlEncodedFormEntity实例将会使用URL编码来编码参数,生成如下的内容:
param1=value1¶m2=%E4%B8%AD%E6%96%87%E5%8F%82%E6%95%B0%E5%80%BC |
内容分块
通常,我们推荐让HttpClient选择基于被传递的HTTP报文属性的最适合的编码转换。这是可能的,但是,设置HttpEntity#setChunked()方法为true是通知HttpClient分块编码的首选。请注意HttpClient将会使用标识作为提示。当使用的HTTP协议版本,如HTTP/1.0版本,不支持分块编码时,这个值会被忽略。
StringEntity entity =new StringEntity("important message", "text/plain; charset=\"UTF-8\""); entity.setChunked(true); HttpPost httppost =new HttpPost("http://localhost/acrtion.do"); httppost.setEntity(entity); |
相关推荐
apache-httpcomponents-httpmime.jar
通过HttpEntity抽象类,可以处理各种类型的数据,如文本、图像或二进制数据。 3. 流处理:HTTPCore引入了InputStream和OutputStream的概念,允许开发者处理HTTP通信中的输入和输出流。这使得可以灵活地处理大文件...
首先,我们来看HTTPComponents Client的核心组件——HttpClient。HttpClient是一个功能丰富的HTTP客户端,可以用来执行各种HTTP方法,如GET、POST、PUT等。它支持基本认证、代理设置、重试策略、连接管理和超时设置...
HttpComponents 是一个开源的 Java 库,用于提供一个强有力的 HTTP 协议支持,帮助用户创建基于 HTTP 协议的客户和服务程序。它包含多个模块,包括 HttpCore、HttpClient、HttpAuth、HttpCookie 等,每个模块都提供...
标签:apache、httpcomponents、httpmime、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准...
标签:apache、httpcomponents、httpmime、中英对照文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明...
标签:apache、httpcomponents、httpcore、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准...
HttpEntity entity = response.getEntity(); // 处理响应实体 } ``` 这些基本的示例展示了如何使用HttpComponents来执行HTTP请求并处理响应。在实际应用中,你可以根据需要配置HttpClient,例如设置超时、添加...
标签:apache、httpcomponents、httpcore、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准...
2. 配置请求,如设置URL、方法类型、请求头和实体内容。 3. 执行请求并获取响应,处理响应状态码和响应体。 示例代码如下: ```java CloseableHttpClient httpClient = HttpClients.createDefault(); ...
4. `NameValuePair`和`HttpEntity`:`NameValuePair`用于构建请求参数,而`HttpEntity`表示HTTP消息的主体,可以是文本、图片或其他类型的数据。 三、POST请求的实现 在Java中,使用HttpClient发送POST请求的基本...
标签:apache、httpcomponents、httpcore、jar包、java、中文文档; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准...
《深入解析Android源码——HTTP网络通信篇》 在Android系统中,网络通信是应用程序与服务器交互的基础,尤其是在移动互联网时代,HTTP协议作为最常用的网络通信协议之一,扮演着至关重要的角色。本篇文章将深入探讨...
标签:apache、httpcomponents、httpcore、jar包、java、API文档、中英对照版; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,...
它主要包括四个主要组件:HttpClient API、HttpTransport、HttpProtocol和HttpEntity。HttpClient API定义了客户端请求和服务器响应的接口;HttpTransport处理网络I/O,如TCP连接和数据传输;HttpProtocol处理HTTP...
在标题提到的`httpcomponents-client-4.2.5-bin.tar`中,我们找到了Apache HttpClient的特定版本4.2.5的二进制分发包,它通常包含了一系列的JAR文件,用于支持网络爬虫和其他需要与HTTP服务器交互的应用程序。...
例如,可以设置Cookie策略,处理gzip压缩的响应,或者使用不同的实体处理器来解析返回的数据。 4. **异步请求**:除了同步请求外,4.2.5版本还支持异步操作,可以非阻塞地发送HTTP请求,进一步提升性能。 二、...
3. **HttpEntity类**:代表HTTP请求或响应的实体,也就是请求体或响应体。你可以使用BasicHttpEntity、StringEntity或UrlEncodedFormEntity等子类来构建不同的实体类型。对于表单提交,通常使用UrlEncodedFormEntity...
《HTTP组件详解——聚焦于Apache HttpComponents》 在IT领域,HTTP(超文本传输协议)是互联网上应用最为广泛的一种网络协议,而Apache HttpComponents则是处理HTTP请求与响应的首选工具包。本篇文章将深入探讨...
HTTPComponents客户端库是Apache软件基金会的一个重要项目,它为Java开发者提供了高效、灵活且可扩展的HTTP客户端API。这个库主要用于处理HTTP协议,包括发送HTTP请求和接收HTTP响应,是Java开发网络应用的必备工具...