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

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重复读问题

背景 在一次业务开发中&#xff0c;由于需要在拦截器中对一个http请求中request body内容做解析和判断&#xff0c;所以用了httpServletRequest的getInputStream解析了request body内容&#xff0c;之后导致了拦截器处理成功后&#xff0c;原来的业务接口处报request body not…...

C++ 类和对象(六)赋值运算符重载

1 运算符重载 C为了增强代码的可读性引入了运算符重载&#xff0c;运算符重载是具有特殊函数名的函数&#xff0c; 也具有其返回值类型&#xff0c;函数名字以及参数列表&#xff0c;其返回值类型与参数列表与普通的函数类似。 函数名字为&#xff1a;关键字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自动扩缩容 举例配置 基于请求数&#xff08;次/秒&#xff09; 指标实现pod自动扩缩容 举例配置 基于 http请求响应时间 (ms) 指标实现pod自动扩缩容 举例配置 基于 Java GC暂停时间 (ms) 指标实现…...

深、浅拷贝之间的关系

深、浅拷贝之间的关系 什么是赋值 赋值是将某一数值或对象赋给某个变量的过程&#xff0c;分为下面 2 部分 基本数据类型&#xff1a;赋值&#xff0c;赋值之后两个变量互不影响引用数据类型&#xff1a;赋址&#xff0c;两个变量具有相同的引用&#xff0c;指向同一个对象&…...

服务器数据恢复-某银行服务器硬盘数据恢复案例

服务器故障&分析&#xff1a; 某银行的某一业务模块崩溃&#xff0c;无法正常使用。排查服务器故障&#xff0c;发现运行该业务模块的服务器中多块硬盘离线&#xff0c;导致上层应用崩溃。 故障服务器内多块硬盘掉线&#xff0c;硬盘掉线数量超过服务器raid阵列冗余级别所允…...

仪器器材经营小程序商城的作用是什么

互联网发展下&#xff0c;数字化转型已经成为常态&#xff0c;仅依赖传统线下经营模式将很难再增长。 作为产品销售及客户维护度高的仪器器材行业&#xff0c;拥有自营商城平台是必要的&#xff0c;不仅可以解决以上难题&#xff0c;还利于打造自身品牌多渠道传播&#xff0c;…...

京东数据分析:2023年9月京东洗烘套装品牌销量排行榜!

鲸参谋监测的京东平台9月份洗烘套装市场销售数据已出炉&#xff01; 根据鲸参谋平台的数据显示&#xff0c;今年9月份&#xff0c;京东平台洗烘套装的销量为7100&#xff0c;环比下降约37%&#xff0c;同比增长约87%&#xff1b;销售额为6000万&#xff0c;环比下降约48%&#…...

论文阅读-多目标强化学习-envelope MOQ-learning

introduction 一种多目标强化学习算法&#xff0c;来自2019 Nips《A Generalized Algorithm for Multi-Objective Reinforcement Learning and Policy Adaptation》本文引用代码全部来源于论文中的链接。主要参考run_e3c_double.py文件 1 总体思想 1.将输入中加入多目标的偏…...

【原创】【考法总结】指针*与++结合的题目考法总结

代码均已调试出结果&#xff0c;放心食用&#xff0c;大致总共5种考法 【理论铺垫】①a[i]恒等价于(ai)即*(&a[0]i)&#xff1b;i类似偏移量&#xff08;别忘a代表数组首元素地址即&a[0]&#xff09; ②*(&a[i])恒等价于a[i]&#xff1a;&a[i]表示a[i]的地址&a…...

react dispatch不生效的坑

一、前言 最近写react antd项目&#xff0c;在A页面中使用了dispatch方法&#xff0c;然后B页面中嵌套A页面&#xff0c;没有问题&#xff1b; 但是在C页面中嵌套A页面的时候&#xff0c;就发现dispatch方法没有执行&#xff0c;也不报错&#xff0c;就很奇怪&#xff1b; 还…...

Mingw快捷安装教程 并完美解决出现的下载错误:The file has been downloaded incorrectly

安装c语言编译器的时候&#xff0c;老是出现The file has been downloaded incorrectly&#xff0c;真的让人 直接去官网拿压缩包&#xff1a;https://sourceforge.net/projects/mingw-w64/files/ &#xff08;往下拉找到那个x86_64-win32-seh的链接&#xff0c;点击后会自动…...

OpenGL —— 2.6、绘制一个正方体并贴图(附源码,glfw+glad)

源码效果 C源码 纹理图片 需下载stb_image.h这个解码图片的库&#xff0c;该库只有一个头文件。 具体代码&#xff1a; vertexShader.glsl #version 330 corelayout(location 0) in vec3 aPos; layout(location 1) in vec2 aUV;out vec2 outUV;uniform mat4 _viewMatrix; u…...

JavaWeb从入门到起飞笔记——导学课程

学完这一节&#xff0c;我不知道学Web开发究竟能干什么&#xff1f;你知道吗&#xff1f; 以下是黑马程序员Java从入门到起飞的笔记 一、学完Javaweb能干什么&#xff1f; 学完Java后我们可以独立开发一些后台管理系统&#xff0c;例如CRMER器&#xff0c;京东和淘宝&#x…...

【LeetCode:1402. 做菜顺序 | 动态规划 + 贪心】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…...

基于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进行逆向分析的过程。通过本文&#xff0c;你将了解到密码加密的基本概念、常用加密算法以及如何通过逆向分析来破解密码。 本文仅供交流学习&#xff0c;勿用于非法用途。 一、密码加…...

人工智能、机器学习、深度学习的区别

人工智能涵盖范围最广&#xff0c;它包含了机器学习&#xff1b;而机器学习是人工智能的重要研究内容&#xff0c;它又包含了深度学习。 人工智能&#xff08;AI&#xff09; 人工智能是一门以计算机科学为基础&#xff0c;融合了数学、神经学、心理学、控制学等多个科目的交…...

Element Plus el-select选择框失去焦点blur

正常情况下&#xff0c;可以使用 el-select 自带的方法 blur 事件来使select失去焦点 示例&#xff1a; <el-select v-model"value" ref"selectRef"><el-optionv-for"item in options":key"item.value":label"item.la…...

Java File与IO流学习笔记

内存中存放的都是临时数据&#xff0c;但是在断电或者程序终止时都会丢失 而硬盘则可以长久存储数据&#xff0c;即使断电&#xff0c;程序终止&#xff0c;也不会丢失 File File是java.io.包下的类&#xff0c;File类的对象&#xff0c;用于代表当前操作系统的文件(可以是文…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析

Linux 内存管理实战精讲&#xff1a;核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用&#xff0c;还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

DBLP数据库是什么?

DBLP&#xff08;Digital Bibliography & Library Project&#xff09;Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高&#xff0c;数据库文献更新速度很快&#xff0c;很好地反映了国际计算机科学学术研…...

Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践

在 Kubernetes 集群中&#xff0c;如何在保障应用高可用的同时有效地管理资源&#xff0c;一直是运维人员和开发者关注的重点。随着微服务架构的普及&#xff0c;集群内各个服务的负载波动日趋明显&#xff0c;传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...

比特币:固若金汤的数字堡垒与它的四道防线

第一道防线&#xff1a;机密信函——无法破解的哈希加密 将每一笔比特币交易比作一封在堡垒内部传递的机密信函。 解释“哈希”&#xff08;Hashing&#xff09;就是一种军事级的加密术&#xff08;SHA-256&#xff09;&#xff0c;能将信函内容&#xff08;交易细节&#xf…...

Linux入门(十五)安装java安装tomcat安装dotnet安装mysql

安装java yum install java-17-openjdk-devel查找安装地址 update-alternatives --config java设置环境变量 vi /etc/profile #在文档后面追加 JAVA_HOME"通过查找安装地址命令显示的路径" #注意一定要加$PATH不然路径就只剩下新加的路径了&#xff0c;系统很多命…...