httpclient教程二:详细执行原理详解

HttpCLient最关键的方法是执行HTTP请求的方法execute。只要把HTTP请求传入,就可以得到HTTP响应

用HttpClient请求一个Http请求的步骤为:

  1. 创建一个HttpClient对象
  2. 创建一个Request对象
  3. 使用HttpClient来执行Request请求,得到对方的response
  4. 处理response
  5. 关闭HttpClient

一、创建一个HttpClient对象

HttpClient的实现类为CloseableHttpClient。创建CloseableHttpClient实例有两种方式

方式一:HttpClients

import org.apache.http.impl.client.HttpClients; // 调用httpClients类

// CloseableHttpClient httpClient = HttpClients.createDefault(); 返回一个CloseableHttpClient类。直接调用方法,看方法前面返回类型 
//                                                                再导入相应的包和实例化对象接收返回值

// 设置线程数
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(100);

// 设置请求和传输超时时间
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(socketTimeout)
    .setConnectTimeout(connectTimeout).build();

// 创建HttpClient对象
CloseableHttpClient httpclient = HttpClients.custom().setConnectionManager(cm)
    .setDefaultRequestConfig(requestConfig).build();

方式二:HttpClientBuilder

先对一些属性进行配置(不断的调用.setxxxxx()方法就行了),再调用build方法来创建实例。

HttpClients.createDefault()实际上调用的也就是HttpClientBuilder.create().build()。

build()方法最终是根据各种配置来new一个InternalHttpClient实例(CloseableHttpClient实现类)

InternalHttpClient底层实现了:HttpCLientConnectionManager、HttpRoutePlanner和RequestConfig,下边分别介绍

(1)HttpCLientConnectionManager:HTTP连接管理器介绍

作用:它负责新HTTP连接的创建、管理连接的生命周期还有保证一个HTTP连接在某一时刻只被一个线程使用

两种具体实现:

1、BasicHttpClientConnectionManager

每次只管理一个connection,所以只能被一个线程使用。它在管理连接的时候如果发现有相同route的请求,会复用之前已经创建的连接,如果新来的请求不能复用之前的连接,它会关闭现有的连接并重新打开它来响应新的请求

2、PoolingHttpClientConnectionManager(多线程的,默认实现)

管理着一个连接池,以同时为多个线程服务。每次新来一个请求,如果在连接池中已经存在route相同并且可用的connection,连接池就会直接复用这个connection;当不存在route相同的connection,就新建一个connection为之服务;如果连接池已满,则请求会等待直到被服务或者超时

setMaxPerRoute(默认值20):总的最大连接数量

setMaxTotal(默认值200):每个route的最大连接数量

如果所有的连接请求都是到同一个url,那可以把MaxPerRoute的值设置成和MaxTotal一致,这样就能更高效地复用连接

(2)HttpRoutePlanner:HttpClient复杂的路由策略以及代理介绍

HttpRoutePlanner是基于http上下文情况下,客户端到服务器的路由计算策略,一般没有代理的话,就不用设置这个东西。这里有一个很关键的概念—Route:在HttpClient中,一个Route指运行环境机器->目标机器host的一条线路,也就是如果目标url的host是同一个,那么它们的route也是一样的

(3)RequestConfig:对request的一些配置

里面比较重要的有三个超时时间,默认的情况下这三个超时时间都为0(如果不设置request的Config,会在execute的过程中使用HttpClientParamConfig的getRequestConfig中用默认参数进行设置),这也就意味着无限等待,很容易导致所有的请求阻塞在这个地方无限期等待。这三个超时时间为:

a、connectionRequestTimeout—从连接池中取连接的超时时间

b、connectTimeout—连接超时时间

c、socketTimeout—请求超时时间

// 设置请求和传输超时时间
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(socketTimeout)
    .setConnectTimeout(connectTimeout).build();

二、创建一个Request对象

HttpClient支持所有的HTTP1.1中的所有定义的请求类型:GET、HEAD、POST、PUT、DELETE、TRACE和OPTIONS。对使用的类为HttpGet、HttpHead、HttpPost、HttpPut、HttpDelete、HttpTrace和HttpOptions。一个Request还可以addHeader、setEntity、setConfig等

创建一个带参数的请求对象:

import org.apache.http.client.methods.HttpGet; // 导入请求包

StringBuffer params = new StringBuffer();
try {
	// 字符数据最好encoding以下;这样一来,某些特殊字符才能传过去(如:某人的名字就是“&”,不encoding的话,传不过去)
	params.append("name=" + URLEncoder.encode("&", "utf-8"));
	params.append("&");
	params.append("age=24");
} catch (UnsupportedEncodingException e1) {
	e1.printStackTrace();
}
HttpGet x =new HttpGet("http://127.0.0.1:777/api/mgr/signin"+"?"+params);

三、执行Request请求

CloseableHttpResponse response = httpClient.execute(x)

HttpContext是跟一个连接相关联的,所以它也只能属于一个线程,如果没有特别设定,在execute的过程中,HttpClient会自动为每一个connection new一个HttpClientHttpContext。

一个execute执行流程:

  1. new一个http context
  2. 取出Request和URL
  3. 根据HttpRoute的配置看是否需要重写URL
  4. 根据URL的host、port和scheme设置target
  5. 在发送前用http协议拦截器处理request的各个部分
  6. 取得验证状态、user token来验证身份
  7. 从连接池中取一个可用的连接
  8. 根据request的各种配置参数以及取得的connection构造一个connManaged
  9. 打开managed的connection(包括创建route、dns解析、绑定socket、socket连接等)
  10. 请求数据(包括发送请求和接收response两个阶段)
  11. 查看keepAlive策略,判断连接是否要复用,并设置相应标识
  12. 返回response
  13. 用http协议拦截器处理response的各个部分

四、处理response

HttpEntity entityTest = response.getEntity();
System.out.println(EntityUtils.toString(entityTest,"utf-8"));

五、关闭连接

response.close();
httpclient.close();

URIBuilder 工具类

httpclient教程二:详细执行原理详解

原创文章,作者:三酷猫,如若转载,请注明出处:https://www.sankumao.com/4210.html

(0)
上一篇 2022年10月22日 下午7:39
下一篇 2022年10月22日 下午9:26

相关推荐

  • TestNG框架教程四:testng.xml文件详解

    TestNG通过设置testng.xml文件能做以下事情 1)创建来源不同包、类、方法的测试套件 2)包括一些选项,例如失败的用例可以重跑。 3)支持使用正则表达式 4)运行把外部…

    2022年10月20日
  • Java+Selenium教程一:环境搭建

    一、谷歌浏览器驱动 1、谷歌各版本下载http://www.chromedownloads.net/chrome64win/ 2、谷歌驱动下载http://npm.taobao.o…

    2022年10月21日
  • Java 开发环境配置

    window系统安装java 出现以下信息,说明环境变量配置成功: 流行JAVA开发工具 正所谓工欲善其事必先利其器,我们在开发java语言过程中同样需要一款不错的开发工具,目前市…

    2022年10月15日
  • Java基础二:数据类型、变量类型、运算符、语法语句

    一、数据类型 java语言提供了八种基本类型。六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型。 数据类型 默认值 byte 0 数据类型是8位、有符号的,以二…

    2022年10月15日
  • Java基础九:集合框架

    早在 Java 2 中之前,Java 就提供了特设类。比如:Dictionary, Vector, Stack, 和 Properties 这些类用来存储和操作对象组。虽然这些类都…

    2022年10月18日
  • Eclipse配置国内镜像源,加速插件下载

    我们在国内从官网下载Eclipse以及插件非常慢,那么,有没有方法变快呢? 有,那就是使用国内的公开镜像源替换官方源。 更换镜像源 网上找到的国内镜像总结 1.企业贡献:&nbsp…

    2022年10月19日
  • Java基础七:面向对象

    继承 1.继承类型 需要注意的是 Java 不支持多继承,但支持多重继承。 2.继承关键字 extends:类的继承是单一继承 implements:接口的继承,可继承多个接口 3…

    2022年10月17日
  • TestNG框架教程一:新手入门

    一、安装JDK和eclipse编辑器 JDK安装,本站教程地址:https://www.sankumao.com/2426.html eclipse安装,下载地址:https://…

    2022年10月18日
  • httpclient教程一:环境搭建

    一、环境准备 将使用eclipse和maven完成本次接口请求实现,以下内容,将默认读者已完成环境准备,包括但不限于JDK、maven、IDEA,并熟练掌握他们的使用方法,如若有不…

    2022年10月22日
  • TestNG框架教程二:断言、前后置方法、分组测试、分Suite测试,@Test()属性

    一、TestNG断言 TestNG的断言种类很多,包括相等/不相等,true/false、为null/不为null、相同/不相同等。 二、前后置方法 注解 描述 @BeforeSu…

    2022年10月19日