前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >HttpClient5升级笔记--API篇

HttpClient5升级笔记--API篇

作者头像
FunTester
发布于 2023-12-26 07:26:04
发布于 2023-12-26 07:26:04
3.3K010
代码可运行
举报
文章被收录于专栏:FunTesterFunTester
运行总次数:10
代码可运行

最近终于是安奈不住升级的冲动,将自己项目的HttpClient版本从4升级到了5,其过程不可谓不艰辛,很多API改动让人无从下手。

Apache HttpClient 5(也称为 HttpClient 5.x)是 Apache HttpComponents 项目中的一个重要组件,用于发送 HTTP 请求和处理 HTTP 响应。它在与网络通信和处理方面提供了许多优势:

  1. 模块化设计: HttpClient 5 采用了模块化的设计,将核心功能拆分为不同的模块。这种设计使得用户可以根据自己的需求选择性地引入和使用不同的功能模块,从而降低了依赖的复杂性。
  2. 高度可定制: 提供了丰富的配置选项和可定制性,允许开发人员根据特定需求配置连接管理、超时、代理、安全策略等参数。
  3. 异步支持: 提供了对异步请求的支持,可以利用异步方式发送请求并处理响应,有助于提高系统的并发能力和性能。
  4. 优化的连接管理: 引入了更灵活和高效的连接管理机制,包括连接池管理、连接复用,可有效减少连接的建立和关闭次数,提高资源利用率。
  5. HTTP/2 支持: 支持 HTTP/2 协议,允许客户端使用 HTTP/2 进行通信,提高了性能和效率,尤其是在处理大量并行请求时。
  6. 最新的标准和协议支持: 支持最新的 HTTP 标准和协议,包括 HTTP/1.1、HTTP/2、TLS/SSL 等,使得 HttpClient 5 在安全性和性能方面都能够保持更新和竞争力。
  7. 优化的代码结构和性能: 重新设计和优化的代码结构,使得 HttpClient 5 在处理请求和响应时更加高效和可靠。
  8. 易于使用的 API: 提供了简单易用的 API,使得发送 HTTP 请求和处理响应变得更加直观和简单。

针对以上好处,本人仅仅感受到了一点点,但是成本远高于好处,经过简单自测,整体感觉没有质的提升。唯一吸引我的还是HTTP/2的支持,不过本地没有开发该协议接口,暂时还没测试,目前主流还是HTTP 1.1。

这是FunTester项目中升级到HttpClient 5的依赖版本。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        <dependency>
            <groupId>org.apache.httpcomponents.client5</groupId>
            <artifactId>httpclient5</artifactId>
            <version>5.3</version>
        </dependency>

其中依赖版本不变,如果你项目里面其他库依赖了HttpClient 4.x版本,记得排除掉,避免干扰。

下面开始分享API改动点,内容不分先后,按照我FunTester项目从上至下列举。以下问容中旧版本指的是4.x,新版指的是5.3。

包名

包名改成了 org.apache.hc.client5. 开头的,需要不少手动工作量。

重试

在旧版本中叫HttpRequestRetryHandler,新版本叫做HttpRequestRetryStrategy,中文应该是重测策略。实现方法上也有所不同。旧版本方法 public boolean retryRequest(IOException exception, int executionCount, HttpContext context) ,而新版本需要实现多个方法:public boolean retryRequest(HttpRequest httpRequest, IOException e, int i, HttpContext httpContext)public boolean retryRequest(HttpResponse httpResponse, int i, HttpContext httpContext)public TimeValue getRetryInterval(HttpResponse httpResponse, int i, HttpContext httpContext) 第一个方法跟旧接口很相似,代码直接可以套用。第二个方法用于对响应信息进行判断重试,这个方法挺不错的,很有市场。第三个方法获取重试间隔,由于我并没有设置改功能,所以并没有什么用。但是大家注意引入了新类 org.apache.hc.core5.util.TimeValue ,在HttpClient 5中,大量使用这个类作为时间配置。

连接配置

新的版本取消了一批API,下面是我旧代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        ConnectionConfig connectionConfig = ConnectionConfig.custom().setMalformedInputAction(CodingErrorAction.IGNORE).setUnmappableInputAction(CodingErrorAction.IGNORE).setCharset(Constant.DEFAULT_CHARSET).setMessageConstraints(messageConstraints).build();

下面是新代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ConnectionConfig connectionConfig = ConnectionConfig.custom()// 设置连接配置  
        .setConnectTimeout(Timeout.of(Duration.ofMillis(CONNECT_TIMEOUT))) // 设置连接超时  
        .setSocketTimeout(Timeout.of(Duration.ofMillis(SOCKET_TIMEOUT))) // 设置 socket 超时  
        .setTimeToLive(Timeout.of(Duration.ofMillis(MAX_ACCEPT_TIME))) // 设置生存时间  
        .setValidateAfterInactivity(Timeout.of(Duration.ofMillis(MAX_ACCEPT_TIME))) // 设置在不活动之后验证  
        .build();

总体讲没有太大差异,后两个配置项对于性能测试来讲也不重要,毕竟连接资源还有连接管理器和异步的资源回收线程负责。

连接池管理器

旧代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 采用绕过验证的方式处理https请求
        // 设置协议http和https对应的处理socket链接工厂的对象
        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create().register("http", PlainConnectionSocketFactory.INSTANCE).register("https", new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE)).build();
        PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry, dnsResolver);
        // 消息约束
        MessageConstraints messageConstraints = MessageConstraints.custom().setMaxHeaderCount(HttpClientConstant.MAX_HEADER_COUNT).setMaxLineLength(HttpClientConstant.MAX_LINE_LENGTH).build();

新代码依旧是取消了一些配置API,其中改动比较大就是创建API,虽然PoolingHttpClientConnectionManager重载构造方法非常多,但是顺序写死了,我只想设置连接配置和DNS解析器,如果用构造方法,必须使用一个N个参数的,非常不优雅。这里推荐builder来完成,我们来看build()方法源码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        PoolingHttpClientConnectionManager poolingmgr = new PoolingHttpClientConnectionManager(RegistryBuilder.create().register(URIScheme.HTTP.id, PlainConnectionSocketFactory.getSocketFactory()).register(URIScheme.HTTPS.id, this.sslSocketFactory != null ? this.sslSocketFactory : (this.systemProperties ? SSLConnectionSocketFactory.getSystemSocketFactory() : SSLConnectionSocketFactory.getSocketFactory())).build(), this.poolConcurrencyPolicy, this.poolReusePolicy, (TimeValue)null, this.schemePortResolver, this.dnsResolver, this.connectionFactory);

默认是有HTTP的连接工厂类注册到连接池管理器中的,所以不用重复设置了,而且也没有预留设置HTTP的API。

异步连接池管理器大差不差,其中有一个TlsStrategy是同步管理器没有的,设置方法如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
.setTlsStrategy(new BasicClientTlsStrategy(sslContext))

builder创建这次新的API用了create()方法,旧的API还是使用custom()。

请求配置

在请求配置中,依然取消了不少API,主要是跟连接怕这出重复的配置项,比较喜欢这种,同一个配置多处配置会导致额外的问题和排查成本,新代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private static RequestConfig getRequestConfig() {  
    return RequestConfig.custom().setConnectionRequestTimeout(Timeout.ofMilliseconds(CONNECT_REQUEST_TIMEOUT)).setCookieSpec("ignoreCookies").setRedirectsEnabled(false).build();  
}

这里有一个cookieSpec的设置比较尴尬,保留了API,却取消了配置项的枚举类,之后先用字符串代替一下,放迷路内容:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Deprecated  
public static final String BROWSER_COMPATIBILITY = "compatibility";  
public static final String NETSCAPE = "netscape";  
public static final String STANDARD = "standard";  
public static final String STANDARD_STRICT = "standard-strict";  
/** @deprecated */  
@Deprecated  
public static final String BEST_MATCH = "best-match";  
public static final String DEFAULT = "default";  
public static final String IGNORE_COOKIES = "ignoreCookies";

在性能测试当中,不需要 CookieStore 来管理cookie,所以选择忽略。

创建HttpClient

我用到了一个新的API org.apache.hc.client5.http.impl.classic.HttpClientBuilder#disableCookieManagement 看源码文档,看着是取消 CookieStore 的配置,因为我两处都设计了,暂时没有发现异常。

拦截器

方法参数多了一个,旧代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
            public void process(HttpResponse httpResponse, HttpContext httpContext)

新代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public void process(HttpResponse httpResponse, EntityDetails entityDetails, HttpContext httpContext)

资源回收

连接池管理器有两个可供调用的资源回收方法,通常会异步调用防止资源异常:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
connManager.closeExpiredConnections();
connManager.closeIdleConnections(HttpClientConstant.IDLE_TIMEOUT, TimeUnit.SECONDS);

新代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
connManager.closeExpired();  
connManager.closeIdle(TimeValue.ofSeconds(IDLE_TIMEOUT));

异步客户端

启动异步客户端的方法start()不变,但是源码中判断逻辑有些区别,特别是在状态属性上。旧代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public void start() {  
    if (this.status.compareAndSet(CloseableHttpAsyncClientBase.Status.INACTIVE, CloseableHttpAsyncClientBase.Status.ACTIVE) && this.reactorThread != null) {  
        this.reactorThread.start();  
    }  
  
}

新代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public final void start() {  
    if (this.status.compareAndSet(AbstractHttpAsyncClientBase.Status.READY, AbstractHttpAsyncClientBase.Status.RUNNING)) {  
        DefaultConnectingIOReactor var10001 = this.ioReactor;  
        this.executorService.execute(var10001::start);  
    }  
  
}

代理

在旧代码中,代理配置可以直接在HttpClient中设置,新代码将API设置为过时,需要在RequestConfig中设置才行,代码不变,如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
setProxy(new HttpHost(ip, port))

请求、响应对象名称

启用了一大批classic开头的对象,例如 org.apache.hc.core5.http.message.BasicClassicHttpRequestorg.apache.hc.core5.http.ClassicHttpResponse ,而且各类封装号的HTTP请求对象的报名也变成了 org.apache.hc.client5.http.classic.methods 。看来这个版本要回归经典了。

实体接口

在旧版代码中,想要处理请求或者响应实体,必须是 org.apache.http.HttpEntityEnclosingRequest 对象,在新版代码中变成了 org.apache.hc.core5.http.HttpEntityContainer ,而且取消了 boolean expectContinue() 方法。

全员携带实体

在旧版代码中,GET和DELETE请求默认是不携带请求实体的,如果想实现该功能需要使用者自己实现,新版中,全员携带实体。这个改变还是很喜闻乐见的。

设置实体

设置实体的API也有少许变动,原来是设置String类型编码格式,现在直接设置 java.nio.charset.Charset ,真是一大进步。

获取header

方法名从 getAllHeader 变成了 getHeaders,别的没了。

响应行

HttpClient 5取消了 获取响应行的的API getStatusLine ,如果想获取状态码,请用:org.apache.hc.client5.http.impl.classic.CloseableHttpResponse#getCode ,个人感觉并不合适,这跟HTTP请求构成有点不一致,但是方便了倒是真的。

获取URI

旧版方法:getURI,返回URI对象,新版:getUri,也返回URI对象,还有一个 getRequestUri 返回String对象。就是大小写的差异,怀疑是不是为了适配代码自动补充的工具。

异步请求

在同步的HttpClient中也是支持异步请求的,旧版代码和同步请求公用请求对象,新版代码增加了新的请求对象:org.apache.hc.client5.http.async.methods.SimpleHttpRequest,这个类明白子类,也不继承于前文提到的 HttpUriRequestBase,感觉就是独立分支一样。同样的响应对象也是 org.apache.hc.client5.http.async.methods.SimpleHttpResponse

HttpClient 5中两者都提供了从同步对象拷贝的方法copy(),奇怪的是请求的拷贝被标记成了过时方法,迷惑行为。从源码中看到可以方便快捷创建GET和POST请求。

响应中有直接获取body的方法 org.apache.hc.client5.http.async.methods.SimpleHttpResponse#getBodyText,看了一下,不太好借鉴到同步方法中。

总结

一个字:折腾。API调用已经完活儿了,后期再根据测试结果分享其他方面的变更感受。

如果没有强需求,不建议升级 HttpClient 5。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-12-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FunTester 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
用深度学习keras的cnn做图像识别分类,准确率达97%
Keras是一个简约,高度模块化的神经网络库。 可以很容易和快速实现原型(通过总模块化,极简主义,和可扩展性) 同时支持卷积网络(vision)和复发性的网络(序列数据)。以及两者的组合。 无缝地运行在CPU和GPU上。 keras的资源库网址为https://github.com/fchollet/keras olivettifaces人脸数据库介绍 Olivetti Faces是纽约大学的一个比较小的人脸库,由 40个人的400张图片构成,即每个人的人脸图片为10张。每张图片的灰度级为8位,每个像素
机器学习AI算法工程
2018/03/15
2.7K0
用深度学习keras的cnn做图像识别分类,准确率达97%
入门项目数字手写体识别:使用Keras完成CNN模型搭建
对于图像分类任务而言,卷积神经网络(CNN)是目前最优的网络结构,没有之一。在面部识别、自动驾驶、物体检测等领域,CNN被广泛使用,并都取得了最优性能。对于绝大多数深度学习新手而言,数字手写体识别任务可能是第一个上手的项目,网络上也充斥着各种各样的成熟工具箱的相关代码,新手在利用相关工具箱跑一遍程序后就能立刻得到很好的结果,这时候获得的感受只有一个——深度学习真神奇,却没能真正了解整个算法的具体流程。本文将利用Keras和TensorFlow设计一个简单的二维卷积神经网络(CNN)模型,手把手教你用代码完成MNIST数字识别任务,便于理解深度学习的整个流程。
用户3578099
2019/08/16
9110
我们建了个模型,搞定了 MNIST 数字识别任务
对于图像分类任务,当前最先进的架构是卷积神经网络 (CNNs).。无论是面部识别、自动驾驶还是目标检测,CNN 得到广泛使用。在本文中,针对著名的 MNIST 数字识别任务,我们设计了一个以 tensorflow 为后台技术、基于 keras 的简单 2D 卷积神经网络 (CNN) 模型。整个工作流程如下:
AI研习社
2018/07/26
7830
我们建了个模型,搞定了 MNIST 数字识别任务
手把手教你使用CNN进行交通标志识别(已开源)
在本文中,使用Python编程语言和库Keras和OpenCV建立CNN模型,成功地对交通标志分类器进行分类,准确率达96%。开发了一款交通标志识别应用程序,该应用程序具有图片识别和网络摄像头实时识别两种工作方式。
小白学视觉
2022/12/28
3.1K0
手把手教你使用CNN进行交通标志识别(已开源)
Keras Callback之RemoteMonitor
Keras提供了一系列的回调函数,用来在训练网络的过程中,查看网络的内部信息,或者控制网络训练的过程。BaseLogger、ProgbarLogger用来在命令行输出Log信息(默认会调用), EarlyStopping、ReduceLROnPlateu分别用来提前终止训练和自动调整学习率,改变网络训练过程;而今天要介绍的RemoteMonitor则用来实时输出网络训练过程中的结果变化情况,包括训练集准确率(accu)、训练集损失值(loss)、验证集准确率(val_acc)、验证集损失值(val_loss),用户也可以自己修改需要显示的数据。一图胜千言,看看下面的结果图吧:
王云峰
2019/12/25
9380
Keras Callback之RemoteMonitor
是选择Keras还是PyTorch开始你的深度学习之旅呢?
原文:https://medium.com/@karan_jakhar/keras-vs-pytorch-dilemma-dc434e5b5ae0
kbsc13
2020/05/22
5860
数字识别,从KNN,LR,SVM,RF到深度学习
@蜡笔小轩V 原文:http://blog.csdn.net/Dinosoft/article/details/50734539 之前看了很多入门的资料,如果现在让我来写写,我觉得我会选择”数字识别(digit recognizer)”作为例子,足够有趣,而且能说明很多问题。kaggle是个实践的好地方,python是门方便的语言,sklearn是个不错的库,文档很适合学习。那就用sklearn来实践一下机器学习,加深理解吧! kaggle数据读取 import pandas as pdimport nu
机器学习AI算法工程
2018/03/13
1.9K0
数字识别,从KNN,LR,SVM,RF到深度学习
Keras介绍
Keras是一个高层神经网络API,Keras由纯Python编写而成并基Tensorflow、Theano以及CNTK后端。Keras 为支持快速实验而生,能够把你的idea迅速转换为结果,如果你有如下需求,请选择Keras:
用户7886150
2021/02/14
1.2K0
TensorFlow快餐教程:程序员快速入门深度学习五步法
作者简介:刘子瑛,阿里巴巴操作系统框架专家;CSDN 博客专家。工作十余年,一直对数学与人工智能算法相关、新编程语言、新开发方法等相关领域保持浓厚的兴趣。乐于通过技术分享促进新技术进步。 作为一个程序员,我们可以像学习编程一样学习深度学习模型开发。我们以 Keras 为例来说明。 我们可以用 5 步 + 4 种基本元素 + 9 种基本层结构,这 5-4-9 模型来总结。 5步法: 1. 构造网络模型 2. 编译模型 3. 训练模型 4. 评估模型 5. 使用模型进行预测 4种基本元素:
用户1737318
2018/07/20
5130
【深度残差收缩网络】超简单Keras代码
从本质上讲,深度残差收缩网络属于卷积神经网络,是深度残差网络(deep residual network, ResNet)的一个变种。它的核心思想在于,在深度学习进行特征学习的过程中,剔除冗余信息是非常重要的;软阈值化是一种非常灵活的、删除冗余信息的方式。
用户6831054
2019/12/31
2.3K0
【深度残差收缩网络】超简单Keras代码
使用 MNIST 集入门 Tensoflow(1)
在入门之前,我们需要开发工具,本文使用 JupyterLab,可以用 conda 或者 pip 方式安装。
coding01
2021/02/24
4270
TensorFlow快餐教程:程序员快速入门深度学习五步法
作为一个程序员,我们可以像学习编程一样学习深度学习模型开发。我们以 Keras 为例来说明。
AI科技大本营
2018/07/23
4320
TensorFlow快餐教程:程序员快速入门深度学习五步法
用多层感知机识别手写体(Keras)
独热编码即 One-Hot-coding,又称一位有效编码,其方法是使用N位状态寄存器来对N个状态进行编码,每个状态都由他独立的寄存器位,并且在任意时候,其中只有一位有效。例如对六个状态进行编码:自然顺序码为 000,001,010,011,100,101独热编码则是 000001,000010,000100,001000,010000,100000
用户3577892
2020/06/11
2.7K0
Auto ML 一种自动完成机器学习任务的系统
在 2018 年比较火,很多大公司都开源了各自的auto ml库,例如 Cloud AutoML, AUTO KERAS, Auto Sklearn, Auto Weka 等,
杨熹
2019/02/20
5540
Auto ML 一种自动完成机器学习任务的系统
Keras-深度学习-神经网络-手写数字识别模型
使用到的数据集为IMDB电影评论情感分类数据集,该数据集包含 50,000 条电影评论,其中 25,000 条用于训练,25,000 条用于测试。每条评论被标记为正面或负面情感,因此该数据集是一个二分类问题。
叶茂林
2023/07/30
2890
Keras-深度学习-神经网络-手写数字识别模型
Keras入门级MNIST手写数字识别超级详细教程
文件下载:https://download.csdn.net/download/sxf1061700625/19229794
小锋学长生活大爆炸
2021/05/30
6.7K0
Keras入门级MNIST手写数字识别超级详细教程
Python人工智能 | 十七.Keras搭建分类神经网络及MNIST数字图像案例分析
从本专栏开始,作者正式研究Python深度学习、神经网络及人工智能相关知识。前一篇文章详细讲解了Keras环境搭建、入门基础及回归神经网络案例。本篇文章将通过Keras实现分类学习,以MNIST数字图片为例进行讲解。基础性文章,希望对您有所帮助!
Eastmount
2022/04/19
1.1K0
Python人工智能 | 十七.Keras搭建分类神经网络及MNIST数字图像案例分析
深度学习|Keras识别MNIST手写数字(一)
MNIST数据集是收集的手写字体,为单色图像,共有训练集60000项,测试数据集10000项。 建模方法我们使用最简单的神经网络模型,多层感知器(MLP)。
罗罗攀
2019/02/22
1.1K0
深度学习|Keras识别MNIST手写数字(一)
基于keras的手写数字识别_数字识别
Flatten层: Flatten层用来将输入“压平”,即把多维的输入一维化,常用在从卷积层到全连接层的过渡,举例如下
全栈程序员站长
2022/10/05
2K0
100天搞定机器学习|day39 Tensorflow Keras手写数字识别
有些教程会推荐安装nightly,它适用于在一个全新的环境下进行TensorFlow的安装,默认会把需要依赖的库也一起装上。我使用的是anaconda,本文我们安装的是纯净版的tensorflow,非常简单,只需打开Prompt:
Ai学习的老章
2019/08/09
5660
100天搞定机器学习|day39 Tensorflow Keras手写数字识别
推荐阅读
相关推荐
用深度学习keras的cnn做图像识别分类,准确率达97%
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验