Request流只能读取一次的问题

SpringBoot 接口加密解密,新姿势!_spring boot 请求加解密-CSDN博客

2.2 request流只能读取一次的问题
2.2.1 问题:
在接口调用链中,request的请求流只能调用一次,处理之后,如果之后还需要用到请求流获取数据,就会发现数据为空。

比如:使用了filter或者aop在接口处理之前,获取了request中的数据,对参数进行了校验,那么之后就不能在获取request请求流了

2.2.2 解决办法
继承HttpServletRequestWrapper,将请求中的流copy一份,复写getInputStream和getReader方法供外部使用。每次调用后的getInputStream方法都是从复制出来的二进制数组中进行获取,这个二进制数组在对象存在期间一致存在。使用Filter过滤器,在一开始,替换request为自己定义的可以多次读取流的request。这样就实现了流的重复获取

InputStreamHttpServletRequestWrapper

package xyz.hlh.cryptotest.utils;import org.apache.commons.io.IOUtils;import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;/*** 请求流支持多次获取*/
public class InputStreamHttpServletRequestWrapper extends HttpServletRequestWrapper {/*** 用于缓存输入流*/private ByteArrayOutputStream cachedBytes;public InputStreamHttpServletRequestWrapper(HttpServletRequest request) {super(request);}@Overridepublic ServletInputStream getInputStream() throws IOException {if (cachedBytes == null) {// 首次获取流时,将流放入 缓存输入流 中cacheInputStream();}// 从 缓存输入流 中获取流并返回return new CachedServletInputStream(cachedBytes.toByteArray());}@Overridepublic BufferedReader getReader() throws IOException {return new BufferedReader(new InputStreamReader(getInputStream()));}/*** 首次获取流时,将流放入 缓存输入流 中*/private void cacheInputStream() throws IOException {// 缓存输入流以便多次读取。为了方便, 我使用 org.apache.commons IOUtilscachedBytes = new ByteArrayOutputStream();IOUtils.copy(super.getInputStream(), cachedBytes);}/*** 读取缓存的请求正文的输入流* <p>* 用于根据 缓存输入流 创建一个可返回的*/public static class CachedServletInputStream extends ServletInputStream {private final ByteArrayInputStream input;public CachedServletInputStream(byte[] buf) {// 从缓存的请求正文创建一个新的输入流input = new ByteArrayInputStream(buf);}@Overridepublic boolean isFinished() {return false;}@Overridepublic boolean isReady() {return false;}@Overridepublic void setReadListener(ReadListener listener) {}@Overridepublic int read() throws IOException {return input.read();}}}

HttpServletRequestInputStreamFilter

package xyz.hlh.cryptotest.filter;import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import xyz.hlh.cryptotest.utils.InputStreamHttpServletRequestWrapper;import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;import static org.springframework.core.Ordered.HIGHEST_PRECEDENCE;/*** @author HLH* @description:*      请求流转换为多次读取的请求流 过滤器* @email 17703595860@163.com* @date : Created in 2022/2/4 9:58*/
@Component
@Order(HIGHEST_PRECEDENCE + 1)  // 优先级最高
public class HttpServletRequestInputStreamFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {// 转换为可以多次获取流的requestHttpServletRequest httpServletRequest = (HttpServletRequest) request;InputStreamHttpServletRequestWrapper inputStreamHttpServletRequestWrapper = new InputStreamHttpServletRequestWrapper(httpServletRequest);// 放行chain.doFilter(inputStreamHttpServletRequestWrapper, response);}
}

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

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

相关文章

彩虹PLM系统:引领汽车行业的数字化转型

彩虹PLM系统&#xff1a;引领汽车行业的数字化转型 彩虹PLM系统作为汽车行业数字化转型的引领者&#xff0c;凭借其卓越的技术实力和丰富的行业经验&#xff0c;为汽车行业带来了全面的解决方案。以下是彩虹PLM系统如何引领汽车行业数字化转型的详细分析&#xff1a; 一、整合全…

约课健身管理系统小程序源码

健身达人的智能助手 一款基于FastAdminThinkPHPUniapp开发的米扬约课健身管理系统&#xff0c;应用于健身房&#xff0c;健身工作室&#xff0c;运动会所&#xff0c;运动场馆&#xff0c;瑜伽馆&#xff0c;拳馆等泛健身行业的场馆中。米扬约课健身致力于为各种健身场馆打造真…

Verilog刷题笔记49——Fsm1同步复位

题目&#xff1a; 解题&#xff1a; module top_module(clk,reset,in,out);input clk;input reset;input in;output out;parameter A0,B1;reg [1:0]current_state,next_state;always(posedge clk)beginif(reset)current_stateB;elsecurrent_statenext_state;endalways(*)beg…

手机图片怎么上传到电脑记事本 保姆级教程

在这个数字化时代&#xff0c;手机成了我们随身携带的摄影棚。无论是旅途中的美景&#xff0c;还是与朋友欢聚的瞬间&#xff0c;手机总能轻松捕捉。然而&#xff0c;手机存储空间有限&#xff0c;那些珍贵的照片和视频&#xff0c;怎样才能安全又方便地保存下来&#xff0c;供…

PFA量杯:精确、实用、高颜值的量杯选择!

您是否在烹饪、实验室实验或日常使用中需要一个精确、实用且高颜值的量杯&#xff1f;PFA量杯是您最佳的选择&#xff01; PFA量杯采用高品质材料制成&#xff0c;具有良好的耐腐蚀性、耐高温性&#xff0c;使用寿命长。透明度极高的杯身&#xff0c;使您在使用时能够清晰地看…

Python项目开发实战:小海龟挑战大迷宫游戏,案例教程编程实例课程详解

一、项目背景与意义 在Python编程学习中,项目实战是检验学习成果、提升编程能力的重要途径。本次项目实战将围绕“小海龟挑战大迷宫”游戏展开,旨在通过构建一个有趣的迷宫游戏,加深对Python语言、海龟图形库(turtle)以及算法逻辑的理解。该项目不仅具有教育意义,还能培养…

自动化脚本存到数据库中有用吗?

一般情况下, 没用! 存到数据库中, 本质上是一种, 代码文件的保存管理, 目的是为了传递和相关的版本管理. 比起这个还得是用git仓库这套要方面, 理由, 有配套的工具和方法论, 有优秀的交流社区, 版本管理和安全的约束也都能够满足. 如果存到数据库中, 则需要自行定义各种使用规…

LLM在软件测试中的革新应用

一、引言 随着人工智能技术的蓬勃发展&#xff0c;大语言模型&#xff08;Large Language Model&#xff0c;简称LLM&#xff09;如GPT系列&#xff0c;在自然语言处理领域取得了显著进展。LLM不仅能够处理复杂的自然语言任务&#xff0c;还在多个领域展现出广泛的应用潜力。在…

深圳网页设计收费情况

深圳是中国最具活力和发展速度最快的城市之一&#xff0c;随着经济的快速发展&#xff0c;各种行业都飞速发展&#xff0c;尤其是互联网行业。网页设计是互联网行业的重要组成部分&#xff0c;深圳的网页设计师数量也是非常庞大的。那么&#xff0c;深圳网页设计师的收费情况是…

MySQL之可扩展性(五)

可扩展性 向外扩展 7.在节点上部署分片 需要确定如何在节点上部署数据分片。以下是一些常用的办法: 1.每个分片使用单一数据库&#xff0c;并且数据库名要相同。典型的应用场景是需要为每个分片都能镜像到原应用的结构。这在部署多个应用实例&#xff0c;并且每个实例对应一…

【Linux学习十八】网站管理:防火墙介绍、静态站点、动态站点、域名

1.Apache Apache官网: www.apache.org 软件包名称: httpd 服务端口:80/tcp(http) 443/tcp(https) 配置文件: /etc/httpd/conf/httpd.conf 子配置文件:/etc/httpd/conf.d/*.conf 查看被占用的端口号 netstat -tuln | grep <端口号> 解哪个程序正在使用端口 80&#xff0…

Jenkins通过Squid代理服务器添加局域网节点机器

✨前言&#xff1a; 当jenkins在公网上的时候&#xff0c;如果要添加局域网内的服务器为节点机器构建的时候&#xff0c;这里就需要通过squid代理服务来实现了。当然你也可以使用其他的方式例如Apache等等&#xff0c;这里主要介绍通过Squid的方式。 &#x1f31f;什么是Squi…

DllImport进阶:参数配置与高级主题探究

深入讨论DllImport属性的作用和配置方法 在基础篇中&#xff0c;我们已经简单介绍了DllImport的一些属性。现在我们将深入探讨这些属性的实际应用。 1. EntryPoint EntryPoint属性用于指定要调用的非托管函数的名称。如果托管代码中的函数名与非托管代码中的函数名不同&#…

【数据结构 之压栈,形参和局部变量入栈之前会发生什么?】三种解释回答 包含操作系统版

有三种解释&#xff0c;前两种是针对程序代码而言的&#xff0c;基本类似&#xff0c;第三种结合了操作系统原理&#xff0c;大家各取所需。 解释一&#xff1a; 在计算机程序执行中&#xff0c;压栈、形参和局部变量的存储过程通常发生在函数调用的时候。在函数被调用时&…

计算机组成原理 | CPU子系统(3)MIPS32指令架构

MIPS32架构指令格式 MIPS32架构寻址方式 指令的编码与功能

文本生成sql模型(PipableAI/pip-sql-1.3b)

安装环境 pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 pip install transformers 代码 question "What are the email address, town and county of the customers who are of the least common gender?"sc…

02--Spring中AOP

目录 16.1 AspectJ框架【AOP框架】 16.2 使用AspectJ步骤 16.3 Spring中AOP概述 16.4 Spring中AOP相关术语 第十七章 AspectJ详解【重点】 17.1 AspectJ中切入点表达式 17.2 AspectJ中JoinPoint对象 17.3 AspectJ中通知 17.4 定义切面优先级 17.5 基于XML方式配置AOP …

203. 移除链表元素【链表】【C++】

题目描述 题目描述 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,6,3,4,5,6], val 6 输出&#xff1a;[1,2,3,4,5] 示例 2&#x…

qiankun 结合 vue3, 小白快速上手体验

一、主应用改造 首先需要维护一份微应用列表&#xff0c;里面包含了微应用的名称、入口和生效规则&#xff0c;若需要给子应用传递内容&#xff0c;可以在 props 传入对应的内容 // app.js const apps [{name: micro-vue-app3,entry: //localhost:3013,container: #micro-vu…

再谈kettle两种循环之--调用http分页接口循环获取数据

再谈kettle两种循环之 – 调用http分页接口循环获取数据 1.场景介绍&#xff1a; 由于数据量比较大,接口有返回限制,需要用到循环分页获取数据 2.案例适用范围&#xff1a; 循环job可参考&#xff0c;变量运用可参考&#xff0c;调用http分页接口循环获取数据可参考&#…