Hutool HttpRequest 首次请求正常 第二次被系统拦截

Hutool HttpRequest 首次请求正常 第二次被系统拦截

  • 功能描述
    • 异常现象
      • 错误代码
    • 异常排查
    • 问题跟踪
    • 问题总结
    • 处理方案
    • 最终修改后的代码

功能描述

需要请求第三方某个接口,获取接口中的数据。

异常现象

使用main 方法 通过Hutool 工具类发出请求,获取数据信息时,发现第一次请求接口可以正常获取数据项,但是循环遍历请求接口时,除首次请求外,其他请求都被第三方接口拦截,提示需要登录。

错误代码

String url = "http://xxx/kk/hh/f?page=1&limit=15";for(int i = 0;i<10;i++){HttpRequest http = HttpRequest.get(url);http.header("Accept", "application/json, text/javascript, */*; q=0.01").header("Accept-Encoding", "gzip, deflate, br").header("Connection", "keep-alive").header("Cookie", "kkid=sdf456sadf45dsf6ds4f; Token=15sd4f5ds6ads54f5sdf45dsf")HttpResponse tt = http.execute();String body = tt.body();}

异常排查

1.由于每次的首次请求都可以成功,排除接口无法请求或做了防重复请求之类的限制。
2.使用 java.net.HttpURLConnection 请求可以正常使用,再次排除接口问题,同时锁定可能是Hutool的问题

问题跟踪

1.跟踪Hutool HttpRequest 的 execute() -> doExecute();

	// 最终执行到这个方法private HttpResponse doExecute(boolean isAsync, Chain<HttpRequest> requestInterceptors, Chain<HttpResponse> responseInterceptors) {// 请求前的拦截方法,可以实现该方法,对请求拦截后处理if (null != requestInterceptors) {Iterator var4 = requestInterceptors.iterator();while(var4.hasNext()) {HttpInterceptor<HttpRequest> interceptor = (HttpInterceptor)var4.next();interceptor.process(this);}}// 获取请求参数this.urlWithParamIfGet();// 初始化连接,此次问题出现在改方法中this.initConnection();// 发送请求this.send();//接受响应信息HttpResponse httpResponse = this.sendRedirectIfPossible(isAsync);if (null == httpResponse) {httpResponse = new HttpResponse(this.httpConnection, this.config, this.charset, isAsync, this.isIgnoreResponseBody());}// 请求响应体拦截,如果项对响应信息做处理,可以实现该方法if (null != responseInterceptors) {Iterator var7 = responseInterceptors.iterator();while(var7.hasNext()) {HttpInterceptor<HttpResponse> interceptor = (HttpInterceptor)var7.next();interceptor.process(httpResponse);}}return httpResponse;}

2.根据首次和其他次的请求,锁定了原因是请求头中的cookie不一致导致,上述方法中的this.initConnection()方法。

	// 初始化httpConnectionprivate void initConnection() {// 判断当前hutool的httpConnection 是否不为空,不为空则关闭连接if (null != this.httpConnection) {this.httpConnection.disconnectQuietly();}// 创建一个新的httpConnection this.httpConnection = HttpConnection.create(this.url.setCharset(this.charset).toURL(this.urlHandler), this.config.proxy).setConnectTimeout(this.config.connectionTimeout).setReadTimeout(this.config.readTimeout).setMethod(this.method).setHttpsInfo(this.config.hostnameVerifier, this.config.ssf).setInstanceFollowRedirects(false).setChunkedStreamingMode(this.config.blockSize).header(this.headers, true);// 判断cookie 是否为空,不为空就设置cookieif (null != this.cookie) {this.httpConnection.setCookie(this.cookie);} else { // 否则就从已经建立的连接中获取cookie(响应体的coolie),添加到cookie中// 由于此处我的cookie 为空,所以直接执行此处,此方法将上一次请求中响应回来的cookie,自动设置到我下一次的请求的请求头中,导致请求头中 key 为Cookie中,导致请求头中有三个key为Cookie的参数,从而导致第三方接口取cookie 时异常,判断非法。GlobalCookieManager.add(this.httpConnection);}if (this.config.isDisableCache) {this.httpConnection.disableCache();}}

3.由于上述方法的cookie 为空,所以直接执行GlobalCookieManager.add(this.httpConnection),此方法将上一次请求中响应回来的cookie,自动设置到我下一次的请求的请求头中,导致请求头中 key 为Cookie中,导致请求头中有三个key为Cookie的参数,从而导致第三方接口取cookie 时异常,判断非法。

	// 添加全局Cookiepublic static void add(HttpConnection conn) {// 判断cookie 管理器是否为空,为空则不对cookie进行操作,此处便是解决问题的关键。if (null != cookieManager) {Map cookieHeader;try {// 从连接中获取上次响应体返回的cookiecookieHeader = cookieManager.get(getURI(conn), new HashMap(0));} catch (IOException var3) {throw new IORuntimeException(var3);}// 将其添加至请求头中,使用的是addRequestProperty,不是setRequestPropertyconn.header(cookieHeader, false);}}

问题总结

Hutool HttpRequest 将上一次请求中响应回来的cookie 添加到下一次的请求头中(key为cookie),
导致第三方使用cookie 验证登录信息的地方失效,从而请求被拦截

处理方案

将 问题跟踪-> 步骤3中 cookieManager 对象设置为空,使其跳过 cookie 设置
由于cookieManager 是个静态对象,其类GlobalCookieManager 中提供setCookieManager 方法
HttpRequest 中也提供 了关闭cookie 的方法(此关闭cookie,就是让cookieManager 对象为空的动作),所以处理方案有两个,经测试,两者都可以实现关闭操作

  1. GlobalCookieManager.setCookieManager(null);
  2. HttpRequest .closeCookie();

最终修改后的代码

String url = "http://xxx/kk/hh/f?page=1&limit=15";
// 此方法为全局方法,如果确实需要此操作,在需要的地方还需再次设置cookieManager  对象HttpRequest .closeCookie()for(int i = 0;i<10;i++){HttpRequest http = HttpRequest.get(url);http.header("Accept", "application/json, text/javascript, */*; q=0.01").header("Accept-Encoding", "gzip, deflate, br").header("Connection", "keep-alive").header("Cookie", "kkid=sdf456sadf45dsf6ds4f; Token=15sd4f5ds6ads54f5sdf45dsf")HttpResponse tt = http.execute();String body = tt.body();}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/161292.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络运维与网络安全 学习笔记2023.11.22

网络运维与网络安全 学习笔记 第二十三天 今日目标 VLAN间通信之交换机、VLAN间通信综合案例、浮动路由 VRRP原理与配置、VRRP链路跟踪、VRRP安全认证 VLAN间通信之交换机 单臂路由的缺陷 在内网的VLAN数量增多时&#xff0c;单臂链路容易成为网络瓶颈 三层交换机 具备…

react中模块化样式中:global的作用

在react中如果是通过import styles from ./index.less这种方式模块化引入样式的话&#xff0c;那么编译后的less文件里的样式名都会自动添加后缀。而:global的作用就是不让类名添加后缀

利用 Apache Ranger 管理 Amazon EMR 中的数据权限

需求背景简介 系统安全通常包括两个核心主题&#xff1a;身份验证和授权。一个解决“用户是谁”的问题&#xff0c;另一个解决“用户允许执行什么操作”的问题。在大数据领域&#xff0c;Apache Ranger 是最受欢迎的授权选择之一&#xff0c;它支持所有主流大数据组件&#xff…

微机原理_1

一、单项选择题(本大题共15小题,每小题3分,共45分。在每小题给出的四个备选项中,选出一个正确的答案,请将选定的答案填涂在答题纸的相应位置上。) 1,下列8086CPU标志寄存器的标志位中,不属于状态标志位的是(&#xff09; A. OF B. IF C. AF D. PF 8086微处理器可寻址访问的最大…

面试中vue-router的一些知识点

Vue Router Vue Router使用举例说明 vue-router 中 route和router的区别与联系 route和router的区别与联系 vue3 路由使用vue2 路由与vue3 路由的区别与联系 Vue Router Vue Router是Vue.js官方的路由管理器&#xff0c;用于实现单页面应用中的路由功能。它允许我们在Vue应用程…

万界星空科技SMT行业生产管理MES系统解决方案

一、SMT行业特点&#xff1a; SMT&#xff08;Surface Mounted Technology&#xff09;作为电子组装行业里首先的技术和工艺&#xff0c;选择合适的MES解决方案来保障SMT生产的成功至关重要。 电子行业涉及的范围非常广&#xff0c;包含了汽车、电脑、电视、手机等产品上&…

HCIA-Datacom跟官方路线学习

通过两次更换策略。最后找到最终的学习方案&#xff0c;华为ICT官网有对这个路线的学习&#xff0c;hcia基础有这个学习路线&#xff0c;hcip也有目录路线。所以&#xff0c;最后制定学习路线&#xff0c;是根据这个认证的路线进行学习了&#xff1a; 官网课程&#xff1a;课程…

scala 实现表达式解析

表达式解析 import org.junit.Testimport scala.collection.mutableclass ExprTestCase {private val orderSource "source_1"private val saleChannel "saleChannel"val datas new mutable.HashMap[String, String]();// p1, source1, sale1, source…

everything的高效使用方法

目录 前言1 everything的简单介绍2 常用搜索3 语法搜索4 正则表达式搜索5 服务器功能 前言 本文介绍everything软件的高效使用方法&#xff0c;everything是一款在系统中快速搜索文件的软件&#xff0c;能够帮助人们快速定位需要查找的文件。首先介绍everything软件的作用和使…

掌握 AI 和 NLP:深入研究 Python — 情感分析、NER 等

一、说明 我们见证了 BERT 等预训练模型在情感分析方面的强大功能,使我们能够破译隐藏在文本数据中的情感。通过 SpaCy,我们探索了命名实体识别的迷人世界,揭开了隐藏在非结构化文本中的秘密。 二、问题陈述 命名实体识别(NER)是自然语言处理中的一项关键…

数字化时代的政务服务:构建便捷高效的线上政务大厅

引言&#xff1a; 随着数字化时代的来临&#xff0c;如何通过线上政务大厅搭建一个便捷高效的服务平台&#xff0c;以更好地满足公众需求值得探究。线上政务大厅是政务服务的新方式&#xff0c;但搭建线上政务大厅并不是一件容易的事情&#xff0c;需要精心的规划和设计。 一…

【蓝桥杯选拔赛真题25】C++两个数比大小 第十三届蓝桥杯青少年创意编程大赛C++编程选拔赛真题解析

目录 C/C++两个数比大小 一、题目要求 1、编程实现 2、输入输出 二、算法分析

Linux文件I/O:基本概念

Linux是一个开源的操作系统&#xff0c;它提供了一套丰富的文件I/O&#xff08;输入/输出&#xff09;接口&#xff0c;让用户和程序可以方便地对文件进行读写操作。文件I/O是操作系统中最基本也最重要的功能之一&#xff0c;它涉及到文件的打开、关闭、读取、写入、定位、锁定…

centos无法进入系统之原因解决办法集合

前言 可爱的小伙伴们&#xff0c;由于精力有限&#xff0c;暂时整理了两类。如果没有你遇到的问题也没有关系&#xff0c;欢迎底下留言评论或私信&#xff0c;小编看到后第一时间帮助解决 一. Centos 7 LVM xfs文件系统修复 情况1&#xff1a; [sda] Assuming drive cache:…

Bean基本注解开发

Commponent 使用Component注解代替<bean>标签 <!--注解扫描:扫描指定的基本包及其子包下的类&#xff0c;识别使用了Component注解的文件--><context:component-scan base-package"org.xfy"></context:component-scan> package org.xfy.Dao.…

【Web】preg_match绕过相关例题wp

目录 ①[FBCTF 2019]rceservice ②[ctfshow]web130 ③[ctfshow]web131 ④[NISACTF 2022]middlerce 简单回顾一下基础 参考文章 p牛神文 preg_match绕过总的来讲就三块可利用 数组绕过、PCRE回溯次数限制、换行符 ①[FBCTF 2019]rceservice 先贴出附件给的源码 &l…

使用electron工具打包web端到PC端应用程序

根据electron官网快速入门示例可以方便的构建mac端包&#xff0c;我们在此基础上构建windows端exe包. 1在package.json文件的script字段增加以下配置 "scripts": {..."build": "electron-builder --win"}, 2然后在终端执行以下命令 npm run b…

Modbus TCP

Modbus &#xff08;&#x1f446; 百度百科&#xff0c;放心跳转&#xff09; 起源 Modbus 由 Modicon 公司于 1979 年开发&#xff0c;是一种工业现场总线协议标准。 Modbus 通信协议具有多个变种&#xff0c;支持串口&#xff0c;以太网多个版本&#xff0c;其中最著名的…

基于STM32的数字图像处理与模式识别算法优化

基于STM32的数字图像处理与模式识别算法优化是一项涉及图像处理和机器学习领域的研究任务&#xff0c;旨在实现高效的图像处理和模式识别算法在STM32微控制器上的运行。本文将介绍基于STM32的数字图像处理与模式识别算法优化的原理和实现步骤&#xff0c;并提供相应的代码示例。…

图神经网络与图注意力网络

随着计算机行业和互联网时代的不断发展与进步&#xff0c;图神经网络已经成为人工智能和大数据的重要研究领域。图神经网络是对相邻节点间信息的传播和聚合的重要技术&#xff0c;可以有效地将深度学习的理念应用于非欧几里德空间的数据上。本期推送围绕图神经网络与图注意力网…