Springboot踩坑-request body重复读问题
背景
在一次业务开发中,由于需要在拦截器中对一个http请求中request body内容做解析和判断,所以用了httpServletRequest的getInputStream解析了request body内容,之后导致了拦截器处理成功后,原来的业务接口处报request body not found的错误。
原理
在使用Springboot开发restful接口的时候,@RequestBody将request body内容注入到参数里时内部是调用getInputStream()方法。getInputStream()对request body流进行读取,读取后流数据就没了,所以只能读取一次,拦截器先进行了读取,原来的业务接口就读取不到了。
解决方案
创建一个类BodyReaderHttpServletRequestWrapper,继承HttpServletRequestWrapper,重写getInputStream和getReader方法,在request.getInputStream之后保存请求体,之后业务代码就可以重复读request body了。
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.springframework.util.StreamUtils;
/**
*
* 从请求体中获取参数请求包装类:<br>
* @author nick
* @version 5.0 since 2018年9月5日
*/
public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper{
private byte[] requestBody = null;//用于将流保存下来
public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
requestBody = StreamUtils.copyToByteArray(request.getInputStream());
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream bais = new ByteArrayInputStream(requestBody);
return new ServletInputStream() {
@Override
public int read() throws IOException {
return bais.read();
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
};
}
@Override
public BufferedReader getReader() throws IOException{
return new BufferedReader(new InputStreamReader(getInputStream()));
}
}
相关文章:
Springboot踩坑-request body重复读问题
背景 在一次业务开发中,由于需要在拦截器中对一个http请求中request body内容做解析和判断,所以用了httpServletRequest的getInputStream解析了request body内容,之后导致了拦截器处理成功后,原来的业务接口处报request body not…...
C++ 类和对象(六)赋值运算符重载
1 运算符重载 C为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数, 也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。 函数名字为:关键字operator后面接需…...
rust学习-trait std::cmp::PartialEq、Eq、PartialOrd、Ord
PartialEq 介绍 pub trait PartialEq<Rhs = Self> whereRhs: ?Sized, {// Required method,后文有讲解这个注释fn eq(&self, other: &Rhs) -> bool;// Provided method,后文有讲解这个注释fn ne(&self, other: &Rhs) -> bool {... } }x.eq(y)…...
k8s pod根据指标自动扩缩容举例
目录 基于 内存 指标实现pod自动扩缩容 举例配置 基于 cpu 指标实现pod自动扩缩容 举例配置 基于请求数(次/秒) 指标实现pod自动扩缩容 举例配置 基于 http请求响应时间 (ms) 指标实现pod自动扩缩容 举例配置 基于 Java GC暂停时间 (ms) 指标实现…...
深、浅拷贝之间的关系
深、浅拷贝之间的关系 什么是赋值 赋值是将某一数值或对象赋给某个变量的过程,分为下面 2 部分 基本数据类型:赋值,赋值之后两个变量互不影响引用数据类型:赋址,两个变量具有相同的引用,指向同一个对象&…...
服务器数据恢复-某银行服务器硬盘数据恢复案例
服务器故障&分析: 某银行的某一业务模块崩溃,无法正常使用。排查服务器故障,发现运行该业务模块的服务器中多块硬盘离线,导致上层应用崩溃。 故障服务器内多块硬盘掉线,硬盘掉线数量超过服务器raid阵列冗余级别所允…...
仪器器材经营小程序商城的作用是什么
互联网发展下,数字化转型已经成为常态,仅依赖传统线下经营模式将很难再增长。 作为产品销售及客户维护度高的仪器器材行业,拥有自营商城平台是必要的,不仅可以解决以上难题,还利于打造自身品牌多渠道传播,…...
京东数据分析:2023年9月京东洗烘套装品牌销量排行榜!
鲸参谋监测的京东平台9月份洗烘套装市场销售数据已出炉! 根据鲸参谋平台的数据显示,今年9月份,京东平台洗烘套装的销量为7100,环比下降约37%,同比增长约87%;销售额为6000万,环比下降约48%&#…...
论文阅读-多目标强化学习-envelope MOQ-learning
introduction 一种多目标强化学习算法,来自2019 Nips《A Generalized Algorithm for Multi-Objective Reinforcement Learning and Policy Adaptation》本文引用代码全部来源于论文中的链接。主要参考run_e3c_double.py文件 1 总体思想 1.将输入中加入多目标的偏…...
【原创】【考法总结】指针*与++结合的题目考法总结
代码均已调试出结果,放心食用,大致总共5种考法 【理论铺垫】①a[i]恒等价于(ai)即*(&a[0]i);i类似偏移量(别忘a代表数组首元素地址即&a[0]) ②*(&a[i])恒等价于a[i]:&a[i]表示a[i]的地址&a…...
react dispatch不生效的坑
一、前言 最近写react antd项目,在A页面中使用了dispatch方法,然后B页面中嵌套A页面,没有问题; 但是在C页面中嵌套A页面的时候,就发现dispatch方法没有执行,也不报错,就很奇怪; 还…...
Mingw快捷安装教程 并完美解决出现的下载错误:The file has been downloaded incorrectly
安装c语言编译器的时候,老是出现The file has been downloaded incorrectly,真的让人 直接去官网拿压缩包:https://sourceforge.net/projects/mingw-w64/files/ (往下拉找到那个x86_64-win32-seh的链接,点击后会自动…...
OpenGL —— 2.6、绘制一个正方体并贴图(附源码,glfw+glad)
源码效果 C源码 纹理图片 需下载stb_image.h这个解码图片的库,该库只有一个头文件。 具体代码: vertexShader.glsl #version 330 corelayout(location 0) in vec3 aPos; layout(location 1) in vec2 aUV;out vec2 outUV;uniform mat4 _viewMatrix; u…...
JavaWeb从入门到起飞笔记——导学课程
学完这一节,我不知道学Web开发究竟能干什么?你知道吗? 以下是黑马程序员Java从入门到起飞的笔记 一、学完Javaweb能干什么? 学完Java后我们可以独立开发一些后台管理系统,例如CRMER器,京东和淘宝&#x…...
【LeetCode:1402. 做菜顺序 | 动态规划 + 贪心】
🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,…...
基于FPGA的图像拉普拉斯变换实现,包括tb测试文件和MATLAB辅助验证
目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a vivado2019.2 3.部分核心程序 timescale 1ns / 1ps // // Company: // Engineer: // // Create Date: 202…...
高校教务系统登录页面JS分析——巢湖学院
高校教务系统密码加密逻辑及JS逆向 本文将介绍高校教务系统的密码加密逻辑以及使用JavaScript进行逆向分析的过程。通过本文,你将了解到密码加密的基本概念、常用加密算法以及如何通过逆向分析来破解密码。 本文仅供交流学习,勿用于非法用途。 一、密码加…...
人工智能、机器学习、深度学习的区别
人工智能涵盖范围最广,它包含了机器学习;而机器学习是人工智能的重要研究内容,它又包含了深度学习。 人工智能(AI) 人工智能是一门以计算机科学为基础,融合了数学、神经学、心理学、控制学等多个科目的交…...
Element Plus el-select选择框失去焦点blur
正常情况下,可以使用 el-select 自带的方法 blur 事件来使select失去焦点 示例: <el-select v-model"value" ref"selectRef"><el-optionv-for"item in options":key"item.value":label"item.la…...
Java File与IO流学习笔记
内存中存放的都是临时数据,但是在断电或者程序终止时都会丢失 而硬盘则可以长久存储数据,即使断电,程序终止,也不会丢失 File File是java.io.包下的类,File类的对象,用于代表当前操作系统的文件(可以是文…...
低查重AI教材编写攻略,掌握这些工具,轻松完成教材创作
教材的初步版本终于完成,但进入修改和优化阶段后,我才意识到这是一种“煎熬”!为了通读全文、查找逻辑上的漏洞和知识点的错误,我费了不少时间;重新调整一个章节的结构,往往会影响到后面的多个部分…...
RPG Maker跨平台解密工具终极实战指南:深度解析资源提取核心技术
RPG Maker跨平台解密工具终极实战指南:深度解析资源提取核心技术 【免费下载链接】RPGMakerDecrypter Tool for decrypting and extracting RPG Maker XP, VX and VX Ace encrypted archives and MV and MZ encrypted files. 项目地址: https://gitcode.com/gh_mi…...
如何完整解锁Cursor Pro功能:一键激活与无限使用的终极指南
如何完整解锁Cursor Pro功能:一键激活与无限使用的终极指南 【免费下载链接】cursor-free-vip [Support 0.45](Multi Language 多语言)自动注册 Cursor Ai ,自动重置机器ID , 免费升级使用Pro 功能: Youve reached you…...
Innovus许可证服务器搭建全记录:从hostid获取到1patch破解的完整流程
Innovus许可证服务器部署实战指南:从环境配置到稳定运行 1. 环境准备与系统优化 在CentOS 7上部署Innovus许可证服务器前,合理的系统配置是确保后续流程顺利的基础。不同于普通应用部署,EDA工具对系统环境有着更为严格的要求。我们建议使用物…...
QT QRadioButton 自定义指示器样式:从入门到精通
1. 初识QRadioButton的指示器 第一次接触QT开发时,我发现QRadioButton默认的圆形指示器样式实在太过普通。那个小小的灰色圆圈,选中时变成黑色圆点,怎么看都像是Windows 95时代的产物。作为一个对UI有追求的开发者,我决定要改变这…...
如何让微信聊天记录成为你的数字记忆银行?WeChatMsg终极指南
如何让微信聊天记录成为你的数字记忆银行?WeChatMsg终极指南 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we…...
硬核算力集结!TMS320C6678、XC7K690T等、匠行科技SBC819模拟信号采集处理板,解锁高端测控新标杆
当信号捕捉遇上极致算力在雷达探测的精准回波中、在高速通信的基带信号流转里、在工业测控的实时监测场景下,信号采集与处理的精度、速度,直接决定系统的核心性能。传统板卡常面临算力不足、数据传输卡顿、环境适配性差等痛点,难以满足高端领…...
别再到处找安装包了!手把手教你从ST官网正确下载STM32CubeMX任意历史版本
从ST官网精准获取STM32CubeMX历史版本的完整指南 作为嵌入式开发者,我们经常需要回退到某个特定的STM32CubeMX版本来兼容旧项目。你可能遇到过这样的困境:官网只提供最新版本下载,而网盘资源又存在安全风险。本文将彻底解决这个痛点ÿ…...
10大决策树实现代码详解:GitHub热门项目实战
10大决策树实现代码详解:GitHub热门项目实战 【免费下载链接】awesome-decision-tree-papers A collection of research papers on decision, classification and regression trees with implementations. 项目地址: https://gitcode.com/gh_mirrors/aw/awesome-d…...
UiPath003 创建基本库
以下教程将引导您完成在 Studio 中创建库,发布库并在其他自动化项目中使用库的步骤。 创建库与创建基本流程类似。区别在于,库是一个包含可重用组件的包,这些组件可以在其他项目的上下文中使用。 本示例从 Excel 电子表格获取数据,…...
