HttpClient 该知道一些概念
HttpClient 该知道不该知道的一些事
一、简介:
- Apache开源项目: http://hc.apache.org/
- 基于HTTP协议提供强大的支持,构建HTTP客户端应用程序
- 执行HTTP协议时,包含了HTTP请求和响应不同状态,可以对关键参数设置和获取
二、HTTP协议(扫盲)
- HTTP请求包含三部分,分别由请求行(请求方法)、请求头(消息报文)、请求正文组成。
- HTTP请求详解:

- HTTP 响应详解

三、URI URL和URN区别:
- URI(Uniform Resource Identifier) 统一资源标识符
- URL(Uniform Resource Locator) 统一资源定位符
- URN(Uniform Resource Name) 统一资源名称
- 整体关系:
- 举个栗子么:
xxxxxxxxxx
http://bitpoetry.io/posts/hello.html#intro
xxxxxxxxxx
http://
xxxxxxxxxx
bitpoetry.io/posts/hello.html
xxxxxxxxxx
#intro
- URL是URI的一个子集,告诉我们访问网络位置的方式,
xxxxxxxxxx
http://bitpoetry.io/posts/hello.html
- URN是URI的子集,包括名字(给定的命名空间内),但不包括访问方式
xxxxxxxxxx
bitpoetry.io/posts/hello.html#intro
四、调用步骤:
- 创建 HttpClient 对象
- 创建请求方法的实例,并指定URL。
- GET 请求,创建 HttpGet 对象
- POST 请求,创建 HttpPost 对象
- 调用 SetParams(HttpParams params) 方法来添加请求参数, 对于 HttpPost 对象而言,也可以调用 setEntity(HttpEntity entity) 方法来设置请求参数
- 调用 HttpClient 对象的 execute(HttpUriRequest request) 发送请求,该方法返回一个 HttpResponse
- 调用 HttpResponse 的 getAllHeaders()、getHeaders(String name) 等方法可获取服务器的响应头;调用 HttpResponse 的 getEntity() 方法可获取 HttpEntity 对象,该对象包装了服务器的相应内容。程序可以通过获取服务器的相应内容
- 释放连接,无论执行方法是否成功,都必须释放连接

五、调用细节:
- HttpClient提供了URIBuilder类来简化和修改请求URI
xxxxxxxxxx
http://image.baidu.com/search/detail?ct=503316480&word=scheme
.setScheme("http") //设置scheme
.setHost("image.baidu.com")//set host
.setPath("/search/detail")// set path
.setParameter("ct","503316480")// set param
.setParameter("word","scheme")
.build();
xxxxxxxxxx
URI uri = new URIBuilder()
.setScheme("http") //设置scheme
.setHost("image.baidu.com")//set host
.setPath("/search/detail")// set path
.setParameter("ct","503316480")// set param
.setParameter("word","scheme")
.build();
- 在Response中几个关键参数获取:
response.getStatusLine().getStatusCode() //状态码
response.getStatusLine().getReasonPhrase()//表单含义
xxxxxxxxxx
response.getProtocolVersion() // 协议
response.getStatusLine().getStatusCode() //状态码
response.getStatusLine().getReasonPhrase()//表单含义
- 获取给定类型的所有头部信息最有效的方式是使用HeaderIterator接口:
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
response.addHeader("Set-Cookie", "c1=a; path=/; domain=localhost");
response.addHeader("Set-Cookie", "c2=b; path=\"/\", c3=c; domain=\"localhost\"");
HeaderElementIterator it = new BasicHeaderElementIterator(response.headerIterator("Set-Cookie"));
while (it.hasNext()) {
HeaderElement elem = it.nextElement();
System.out.println(elem.getName() + " = " + elem.getValue());
NameValuePair[] params = elem.getParameters();
for (int i = 0; i < params.length; i++) {
System.out.println(" " + params[i]);
}
}
}
运行输出:
c1 = a
path=/
domain=localhost
c2 = b
path=/
c3 = c
domain=localhost
xxxxxxxxxx
public static void main(String[] args) {
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
response.addHeader("Set-Cookie", "c1=a; path=/; domain=localhost");
response.addHeader("Set-Cookie", "c2=b; path=\"/\", c3=c; domain=\"localhost\"");
HeaderElementIterator it = new BasicHeaderElementIterator(response.headerIterator("Set-Cookie"));
while (it.hasNext()) {
HeaderElement elem = it.nextElement();
System.out.println(elem.getName() + " = " + elem.getValue());
NameValuePair[] params = elem.getParameters();
for (int i = 0; i < params.length; i++) {
System.out.println(" " + params[i]);
}
}
}
运行输出:
c1 = a
path=/
domain=localhost
c2 = b
path=/
c3 = c
domain=localhost
- 为了保证系统资源被正确地释放,我们要么管理HTTP实体流,要么关闭http响应。
- 关闭HTTP实体内容流和关闭HTTP响应的区别,前者通过消耗掉HTTP实体内容来保持相关HTTP连接,然而后者会立即关闭,丢弃HTTP连接。
- HttpClient 推荐使用 HttpEntity 的 getContent() 方法或者 HttpEntity 的 writeTo(OutputStream) 方法读取Http实体内容。
- EntityUtils 提供的方法可以以字符串或者字节数组的形式读取 Http 实体,但是一般不建议,确保相应的实体长度不大。
- 希望把 Http 实体内容缓存在内存或者磁盘上,最简单方法就是把 Http Entity 转化为 BufferedHttpEntity,
HttpEntity entity = response.getEntity();
if (entity != null) {
entity = new BufferedHttpEntity(entity);
}
xxxxxxxxxx
CloseableHttpResponse response = <...>
HttpEntity entity = response.getEntity();
if (entity != null) {
entity = new BufferedHttpEntity(entity);
}
- HttpClient 提供了一些类,这些类可以通过http连接高效地输出Http实体内容。
- HttpClient 提供的这几个类涵盖的常见的数据类型,如String,byte 数组,输入流,和文件类型:StringEntity,ByteArrayEntity,InputStreamEntity,FileEntity。
FileEntity entity = new FileEntity(file,
ContentType.create("text/plain", "UTF-8"));
HttpPost httppost = new HttpPost("http://localhost/action.do");
httppost.setEntity(entity);
xxxxxxxxxx
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);
- 请注意由于 InputStreamEntity 只能从下层的数据流中读取一次,所以它是不能重复的。推荐,通过继承 HttpEntity 这个自包含的类来自定义HttpEntity 类,而不是直接使用 InputStreamEntity 这个类。FileEntity 就是一个很好的起点(FileEntity 就是继承的 HttpEntity)。
- 模拟 HTML 表单提交
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);
xxxxxxxxxx
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);
- 设置传输编码方式(1.0不支持)
ContentType.create("plain/text", Consts.UTF_8));
entity.setChunked(true);
HttpPost httppost = new HttpPost("http://localhost/acrtion.do");
httppost.setEntity(entity);
xxxxxxxxxx
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);
- 处理http响应的方法就是使用ResponseHandler接口,这个接口中有handleResponse(HttpResponse response)方法。使用这个方法,用户完全不用关心http连接管理器。当使用ResponseHandler时,HttpClient会自动地将Http连接释放给Http管理器,即使http请求失败了或者抛出了异常。
HttpGet httpget = new HttpGet("http://localhost/json");
ResponseHandler<MyJsonObject> rh = new ResponseHandler<MyJsonObject>() {
@Override
public JsonObject handleResponse(
final HttpResponse response) throws IOException {
StatusLine statusLine = response.getStatusLine();
HttpEntity entity = response.getEntity();
if (statusLine.getStatusCode() >= 300) {
throw new HttpResponseException(
statusLine.getStatusCode(),
statusLine.getReasonPhrase());
}
if (entity == null) {
throw new ClientProtocolException("Response contains no content");
}
Gson gson = new GsonBuilder().create();
ContentType contentType = ContentType.getOrDefault(entity);
Charset charset = contentType.getCharset();
Reader reader = new InputStreamReader(entity.getContent(), charset);
return gson.fromJson(reader, MyJsonObject.class);
}
};
MyJsonObject myjson = client.execute(httpget, rh);
xxxxxxxxxx
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpget = new HttpGet("http://localhost/json");
ResponseHandler<MyJsonObject> rh = new ResponseHandler<MyJsonObject>() {
@Override
public JsonObject handleResponse(
final HttpResponse response) throws IOException {
StatusLine statusLine = response.getStatusLine();
HttpEntity entity = response.getEntity();
if (statusLine.getStatusCode() >= 300) {
throw new HttpResponseException(
statusLine.getStatusCode(),
statusLine.getReasonPhrase());
}
if (entity == null) {
throw new ClientProtocolException("Response contains no content");
}
Gson gson = new GsonBuilder().create();
ContentType contentType = ContentType.getOrDefault(entity);
Charset charset = contentType.getCharset();
Reader reader = new InputStreamReader(entity.getContent(), charset);
return gson.fromJson(reader, MyJsonObject.class);
}
};
MyJsonObject myjson = client.execute(httpget, rh);
HttpClient 该知道一些概念的更多相关文章
- HttpClient学习之 客户端HTTP编程入门
说明 本文存在的原因,是想深入的学习下HttpClient.对应的网址是: http://hc.apache.org/httpcomponents-client-4.5.x/primer.html h ...
- Vert.x学习之 Web Client
Vert.x Web Client 原文档 组件源码 组件示例 中英对照表 Pump:泵(平滑流式数据读入内存的机制,防止一次性将大量数据读入内存导致内存溢出) Response Codec:响应编解 ...
- Java 爬虫遇到需要登录的网站,该怎么办?
这是 Java 网络爬虫系列博文的第二篇,在上一篇 Java 网络爬虫,就是这么的简单 中,我们简单的学习了一下如何利用 Java 进行网络爬虫.在这一篇中我们将简单的聊一聊在网络爬虫时,遇到需要登录 ...
- HttpClientFactory-向外请求的最佳
简介 它的组件包是Microsoft.Extensions.Http 复原HttpClient带来的问题 HttpClient相关问题 虽然HttpClient类实现了IDisposable,但不是首 ...
- 爬虫概念与编程学习之如何爬取视频网站页面(用HttpClient)(二)
先看,前一期博客,理清好思路. 爬虫概念与编程学习之如何爬取网页源代码(一) 不多说,直接上代码. 编写代码 运行 <!DOCTYPE html><html><head& ...
- 揭秘Windows10 UWP中的httpclient接口[2]
阅读目录: 概述 如何选择 System.Net.Http Windows.Web.Http HTTP的常用功能 修改http头部 设置超时 使用身份验证凭据 使用客户端证书 cookie处理 概述 ...
- 大叔也说Xamarin~Android篇~为HttpClient共享Session,android与api的session共享机制
回到目录 杂谈 在进行android进行开发时,我们的数据一般通过接口来获收,这里指的接口泛指web api,webservice,wcf,web应用程序等:它们做为服务端与数据库进行直接通讯,而AP ...
- [Android] HttpURLConnection & HttpClient & Socket
Android的三种网络联接方式 1.标准Java接口:java.net.*提供相关的类//定义地址URL url = new URL("http://www.google.com" ...
- Android系列之网络(一)----使用HttpClient发送HTTP请求(通过get方法获取数据)
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
随机推荐
- C开发系列-指针
指针 通过一段简单的程序,引入指针的概念 #include <iostream> using namespace std; // changeValue函数的定义 void changeV ...
- Windows API 第四篇 文件操作
创建或打开文件(也可用于打开管道,油槽,硬件设备等): HANDLE CreateFile( LPCTSTR lpFileName, // file name DWORD dwDesiredAcces ...
- node概览和安装
一.node是一个平台环境,可以运行js代码的服务器端平台. 设计最初node是用来解决并发问题的,现在可以用来放在服务端使用. node平台的有优点:运行速度快,支持高并发,轻便.小巧 但是与jav ...
- js的相关距离
js的相关距离 一.dom对象的距离 ---dom.style.width : 对象本身的内容宽度(这里必须是内联样式中的width,带px)(content) ---dom.style.height ...
- str_replace函数的使用规则和案例详解
str_replace函数的使用规则和案例详解 str_replace函数的简单调用: <?php $str = '苹果很好吃.'; //请将变量$str中的苹果替换成香蕉 $strg = st ...
- [jeecms]获取父栏目下的子栏目名称
[@cms_channel_list parentId='父栏目id'] [#list tag_list as c] <a href="${c.url}">${c.na ...
- vue项目打包部署到服务器,静态资源文件404
js文件404问题 原因:打包的项目静态资源的路径需要设置为绝对路径.如果是相对路径会出错 解决办法:修改config/index.js文件,将 assetsPublicPath修改为' ...
- python学习笔记1_import与from方法总结
一.模块&包简介 模块:所谓模块就是一个.py文件,用来存放变量,方法的文件,便于在其他python文件中导入(通过import或from). 包(package): 包是更大的组织单位,用来 ...
- tp5 报 A non well formed numeric value encountered 的错解决办法
thinkphp5出现A non well formed numeric value encountered的解决办法修改formatDateTime方法如下 默认值: if (is_null($th ...
- 基于MaxCompute的媒体大数据开放平台建设
摘要:随着自媒体的发展,传统媒体面临着巨大的压力和挑战,新华智云运用大数据和人工智能技术,致力于为媒体行业赋能.通过媒体大数据开放平台,将媒体行业全网数据汇总起来,借助平台数据处理能力和算法能力,将有 ...