当前位置: 首页 > news >正文

springboot http添加请求头 添加请求证书

首先明确两个事情:请求对象,连接对象

我们知道你要是想发起一个请求,需要指定两个环节内容,一个是请求内容对象(request),一个是连接内容对象(httpClient)
它们两个的作用我们在下面会看到

简要分析源码

1.先说一下结论,spring所有的核心代码都在doxxx()方法里面,而http请求的核心代码在doExecute()中。

# 我们平时会写这个一个方法去开启http请求调用
restTemplate.postForObject(url,httpEntity, xxx.class);# 往里钻
@Nullablepublic <T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables) throws RestClientException {RequestCallback requestCallback = this.httpEntityCallback(request, responseType);HttpMessageConverterExtractor<T> responseExtractor = new HttpMessageConverterExtractor(responseType, this.getMessageConverters(), this.logger);return this.execute(url, HttpMethod.POST, requestCallback, responseExtractor, (Object[])uriVariables);}#继续钻,发现了doxxx()方法
@Nullablepublic <T> T execute(String url, HttpMethod method, @Nullable RequestCallback requestCallback, @Nullable ResponseExtractor<T> responseExtractor, Object... uriVariables) throws RestClientException {URI expanded = this.getUriTemplateHandler().expand(url, uriVariables);return this.doExecute(expanded, method, requestCallback, responseExtractor);}#看看实现,我们会发现有一个创建request的操作
@Nullableprotected <T> T doExecute(URI url, @Nullable HttpMethod method, @Nullable RequestCallback requestCallback, @Nullable ResponseExtractor<T> responseExtractor) throws RestClientException {Assert.notNull(url, "URI is required");Assert.notNull(method, "HttpMethod is required");ClientHttpResponse response = null;Object var14;try {# 核心!!!ClientHttpRequest request = this.createRequest(url, method);if (requestCallback != null) {requestCallback.doWithRequest(request);}response = request.execute();this.handleResponse(url, method, response);var14 = responseExtractor != null ? responseExtractor.extractData(response) : null;} catch (IOException var12) {String resource = url.toString();String query = url.getRawQuery();resource = query != null ? resource.substring(0, resource.indexOf(63)) : resource;throw new ResourceAccessException("I/O error on " + method.name() + " request for \"" + resource + "\": " + var12.getMessage(), var12);} finally {if (response != null) {response.close();}}return var14;}# 我们发现所有的request对象都是通过factory创建的,不同的factory会创建不同的request对象
# 因为目前我们位于抽象类HttpAccessor中,所以我们要继续往实现类追踪getRequestFactory()方法
protected ClientHttpRequest createRequest(URI url, HttpMethod method) throws IOException {ClientHttpRequest request = this.getRequestFactory().createRequest(url, method);this.initialize(request);if (this.logger.isDebugEnabled()) {this.logger.debug("HTTP " + method.name() + " " + url);}return request;}# 此时我们位于InterceptingHttpAccessor抽象类中,继续往下追踪就是RestInterceptors类了,没有重写getRequestFactory()方法,所以我们要重点关注InterceptingHttpAccessor抽象类中的重写逻辑:
public ClientHttpRequestFactory getRequestFactory() {List<ClientHttpRequestInterceptor> interceptors = this.getInterceptors();if (!CollectionUtils.isEmpty(interceptors)) {ClientHttpRequestFactory factory = this.interceptingRequestFactory;if (factory == null) {// 如果有interceptors,则融合父类的factory和interceptors,返回一个新的factory来覆盖原有父类factoryfactory = new InterceptingClientHttpRequestFactory(super.getRequestFactory(), interceptors);this.interceptingRequestFactory = (ClientHttpRequestFactory)factory;}return (ClientHttpRequestFactory)factory;} else {// 如果没有则interceptors,则直接用父类中的factory,return super.getRequestFactory();}}

至此,我们可以得到以下结论,如果想对原有请求进行扩展,我们需要从两个对象进行下手:factory,interceptor。

接下来我们看一下factory和interceptor两个类中都有什么内容:

#factory
public class HttpComponentsClientHttpRequestFactory implements ClientHttpRequestFactory, DisposableBean {// 重点关注!!!连接对象private HttpClient httpClient;@Nullableprivate RequestConfig requestConfig;private boolean bufferRequestBody = true;@Nullableprivate BiFunction<HttpMethod, URI, HttpContext> httpContextFactory;
}#interceptor
public interface ClientHttpRequestInterceptor {// 重点关注!!!request对象ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException;
}

我们可以发现在factory中我们可以对连接对象进行修改,在interceptor中可以对请求对象进行修改;我们回归下文章开头,一个请求的两个组成部分我们已经发现了。接下来就演示下不同场景应该怎么使用这两种对象。

场景1:添加固定请求头

分析:请求头内容属于请求对象,所以我们通过interceptor来实现

@Configuration
public class RestTemplateConfig {/*** restTemplate*/@ConditionalOnMissingBean@Beanpublic RestTemplate restTemplate(ClientHttpRequestFactory factory) {RestTemplate restTemplate = new RestTemplate();ClientHttpRequestInterceptor clientHttpRequestInterceptor = new ClientHttpRequestInterceptor() {@Overridepublic ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)throws IOException {request.getHeaders().set("X-ID", "");request.getHeaders().set("X-APPKEY", "");return execution.execute(request, body);}};restTemplate.setInterceptors(Collections.singletonList(clientHttpRequestInterceptor));return restTemplate;}
}

场景二:添加请求证书

分析:请求头内容属于连接对象,所以我们通过factory来实现

public static HttpComponentsClientHttpRequestFactory generateHttpRequestFactory() {TrustStrategy acceptingTrustStrategy = (x509Certificates, authType) -> true;SSLContext sslContext = null;try {sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy)// 增加请求证书.loadKeyMaterial(ks, keyStorePassword.toCharArray()).setProtocol("TLSv1.2").build();} catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) {log.error("generateHttpRequestFactory failed:", e);}SSLConnectionSocketFactory connectionSocketFactory =new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier());HttpClientBuilder httpClientBuilder = HttpClients.custom();httpClientBuilder.setSSLSocketFactory(connectionSocketFactory);CloseableHttpClient httpClient = httpClientBuilder.build();HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();factory.setHttpClient(httpClient);factory.setConnectTimeout(15000);factory.setReadTimeout(5000);return factory;
}

当然两者可以同时存在:

public RestTemplate restTemplate(ClientHttpRequestFactory factory) {// 修改factoryRestTemplate restTemplate = new RestTemplate(generateHttpRequestFactory());ClientHttpRequestInterceptor clientHttpRequestInterceptor = new ClientHttpRequestInterceptor() {@Overridepublic ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)throws IOException {request.getHeaders().set("X-HW-ID", "com.huawei.osec");request.getHeaders().set("X-HW-APPKEY", "/D2QodV7Lu2EUk4D9HEUsQ==");return execution.execute(request, body);}};// 修改interceptorrestTemplate.setInterceptors(Collections.singletonList(clientHttpRequestInterceptor));return restTemplate;}

相关文章:

springboot http添加请求头 添加请求证书

首先明确两个事情&#xff1a;请求对象&#xff0c;连接对象 我们知道你要是想发起一个请求&#xff0c;需要指定两个环节内容&#xff0c;一个是请求内容对象(request)&#xff0c;一个是连接内容对象(httpClient) 它们两个的作用我们在下面会看到 简要分析源码 1.先说一下…...

【Qt之数据库操作】

使用Qt实现SQLite数据库操作可以分为以下几个步骤&#xff1a; 添加SQLite头文件和库文件&#xff1a; 在Qt项目中&#xff0c;需要在.pro文件中添加以下内容&#xff1a; QT sql打开/创建数据库&#xff1a; 可以使用QSqlDatabase类中的静态函数addDatabase()来添加数据库…...

数据结构(c语言版) 队列

链队列 要求&#xff1a;实现链队列的创建、初始化、入队、出队 &#xff08;先进先出&#xff09; 代码 // // Created by My.cy on 2023/10/19. // //链队列 创建、初始化、入队、出队 先进先出#include <stdio.h> #include <malloc.h>//定义结构体 struct…...

kimera论文阅读

文章目录 功能构成&#xff1a;Kimera线程A. Kimera-VIO:B. Kimera-RPGO:C. Kimera-Mesher:D. Kimera-Semantics:E.调试工具 功能构成&#xff1a; Kimera包括四个关键模块: Kimera-VIO的核心是基于gtsam的VIO方法[45]&#xff0c;使用IMUpreintegration和无结构视觉因子[27]…...

golang gorm通过泛型实现通用单表增删改

golang gorm通过泛型实现通用单表增删改 无废话&#xff0c;直接上代码 想实现通用&#xff0c;首先得实现查询的通用&#xff0c;可以用传递map实现 func Where(where map[string]interface{}) func(db *gorm.DB) *gorm.DB {return func(db *gorm.DB) *gorm.DB {dbTmp : db…...

十、K8S之ConfigMap

ConfigMap 一、概念 在K8S中&#xff0c;ConfigMap是一种用于存储配置数据的API对象&#xff0c;一般用于存储Pod中应用所需的一些配置信息&#xff0c;或者环境变量。将配置于 Pod 分开&#xff0c;避免应为修改配置导致还需要重新构建 镜像与容器。 二、创建 可以使用 ku…...

python飞书群机器人通过webhook发送消息

python飞书群机器人通过webhook发送消息 import json import loggingimport requestslogger logging.getLogger(__name__) logging.basicConfig(levellogging.DEBUG)class FeishuTalk:"""飞书群机器人通过webhook发送消息"""def __init__(self…...

埃隆·马斯克的 AI 聊天机器人 Grok 已经上线

昨天&#xff0c;埃隆马斯克 (Elon Musk) 通过他的公司 xAI 推出了一款名为 Grok 的新型人工智能聊天机器人。这款新的聊天机器人将通过 Twitter 更新实时获取世界知识&#xff0c;使其成为最新的对话 AI 系统。 Grok 的独特和基本优势在于它可以通过 &#x1d54f; 平台实时了…...

【代码随想录】算法训练营 第十五天 第六章 二叉树 Part 2

102. 二叉树的层序遍历 层序遍历&#xff0c;就是一层一层地遍历二叉树&#xff0c;最常见的就是从上到下&#xff0c;从左到右来遍历&#xff0c;遍历的方法依然有两种&#xff0c;第一种是借助队列&#xff0c;第二种则是递归&#xff0c;都算是很简单、很容易理解的方法&am…...

使用ssl_certificate_by_lua指令动态加载证书

1、下载 OpenResty - 下载 根据自己系统选择下载&#xff0c;我的是64位 2、解压到目录 3、启动openresty 进入解压后的目录&#xff0c;执行nginx.exe 浏览器输入 http://localhost 查看是否正常。显示以下画面就表示没有问题。 接下来可以开始准备动态安装证书 4、使用o…...

Qt中Opencv转Qimage出现重影或者颜色不对

废话不多说 在qt中opencv获取的图像转qimage时出现重影原因&#xff1a; 图像数据的内存对齐可能会导致画面重影&#xff0c;如果出现误差转换出来的图就会出现重影 解决办法&#xff1a; cv::Mat image_bgr cv::imread(“example.jpg”); cv::Mat image_aligned; cv::copyMak…...

upload-labs-1

文章目录 Pass-01 Pass-01 先上传一个正常的图片&#xff0c;查看返回结果&#xff0c;结果中带有文件上传路径&#xff0c;可以进行利用&#xff1a; 上传一个恶意的webshell&#xff0c;里面写入一句话木马&#xff1a; <?php eval($_POST[cmd]); echo "hello&quo…...

【vite配置路径别名@】/启动配置

npm install types/node --save-dev npm install path --save import { defineConfig } from vite import vue from vitejs/plugin-vue // 配置别名 import { resolve } from "path";// https://vitejs.dev/config/ export default defineConfig({plugins: [vue()]…...

3. List

数据结构在Java集合中的对应关系 线性表【数组】 -> ArrayList 线性表【链表】-> LinkedList 队列 -> Queue -> LinkedList&#xff0c;PriorityQueue, ArrayBlockingQueue … etc. 双端队列 -> Deque -> ArrayDeque 栈 -> LinkedList 哈希表 -> Hash…...

Django初窥门径-oauth登录认证

引言 在现代Web应用程序中&#xff0c;用户身份验证和授权是至关重要的组成部分。Django&#xff0c;一个流行的Python Web框架&#xff0c;为用户身份验证提供了内置支持。本文将探讨如何创建和注册Django应用&#xff0c;自定义身份验证服务&#xff0c;配置AUTHENTICATION_…...

数学到底在哪里支撑着编程?

数学到底在哪里支撑着编程&#xff1f; 除了少数算法等明显相关情况外&#xff0c;说点日常的。 编程是个极度依赖逻辑的领域&#xff0c;逻辑严谨性好&#xff0c;你的编程工作会顺畅很多一-绝大多 数的bug都是最近很多小伙伴找我&#xff0c;说想要一些嵌入式的资料&#x…...

Python模块ADB的, 已经 pyadb

Python模块ADB的使用指南_笔记大全_设计学院 (python100.com) pip install adb Python 调用ADB_python 调用adb命令_实相实相的博客-CSDN博客 Python ADB.shell_command Examples, pyadb.ADB.shell_command Python Examples - HotExamples Gitee 极速下载/PyADB - 码云 - 开…...

猫头虎分享从Python到JavaScript传参数:多面手的数据传递术

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…...

注解汇总:Spring 常用的注解

前言 本栏目的内容已经讲完了&#xff0c;本案例将把案例中所有讲到的注解都汇总起来&#xff0c;方便日后的学习需要用到的时候能够快速的找到相应的注解。本案例将结合小案例一起做汇总&#xff0c;也想丹玉是再复习一遍讲过用过的注解。 一、注解汇总 1、Component Reposi…...

合肥工业大学操作系统实验5

✅作者简介:CSDN内容合伙人、信息安全专业在校大学生🏆 🔥系列专栏 :hfut实验课设 📃新人博主 :欢迎点赞收藏关注,会回访! 💬舞台再大,你不上台,永远是个观众。平台再好,你不参与,永远是局外人。能力再大,你不行动,只能看别人成功!没有人会关心你付出过多少…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

python打卡day49

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表

1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

C#中的CLR属性、依赖属性与附加属性

CLR属性的主要特征 封装性&#xff1a; 隐藏字段的实现细节 提供对字段的受控访问 访问控制&#xff1a; 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性&#xff1a; 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑&#xff1a; 可以…...

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...

stm32进入Infinite_Loop原因(因为有系统中断函数未自定义实现)

这是系统中断服务程序的默认处理汇编函数&#xff0c;如果我们没有定义实现某个中断函数&#xff0c;那么当stm32产生了该中断时&#xff0c;就会默认跑这里来了&#xff0c;所以我们打开了什么中断&#xff0c;一定要记得实现对应的系统中断函数&#xff0c;否则会进来一直循环…...

P10909 [蓝桥杯 2024 国 B] 立定跳远

# P10909 [蓝桥杯 2024 国 B] 立定跳远 ## 题目描述 在运动会上&#xff0c;小明从数轴的原点开始向正方向立定跳远。项目设置了 $n$ 个检查点 $a_1, a_2, \cdots , a_n$ 且 $a_i \ge a_{i−1} > 0$。小明必须先后跳跃到每个检查点上且只能跳跃到检查点上。同时&#xff0…...

MLP实战二:MLP 实现图像数字多分类

任务 实战&#xff08;二&#xff09;&#xff1a;MLP 实现图像多分类 基于 mnist 数据集&#xff0c;建立 mlp 模型&#xff0c;实现 0-9 数字的十分类 task: 1、实现 mnist 数据载入&#xff0c;可视化图形数字&#xff1b; 2、完成数据预处理&#xff1a;图像数据维度转换与…...