使用AOP在切面逻辑中无法获取到requesetBody
使用场景:在接口处理之前,我们需要拿到请求参数,对参数进行校验。注意,这里需要拿到的是原始的请求信息!
一般的获取方式
ServletInputStream inputStream = request.getInputStream();
StringBuilder stringBuilder = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, request.getCharacterEncoding()))) {String line;while ((line = reader.readLine()) != null) {stringBuilder.append(line);}
} catch (IOException e) {e.printStackTrace();
}
String requestBody = stringBuilder.toString();
获取requestBody的代码大同小异,可自行搜索。代码没有问题,但是无法获取到requestBody,就要考虑接口方法是否使用了@RequestBody。
在Spring MVC框架中,当你使用@RequestBody注解时,Spring会在将请求转发到控制器方法之前,从HTTP请求体中读取数据并将其反序列化为Java对象。这一处理过程是由HttpMessageConverter完成的,它负责将请求体中的JSON、XML或其他格式的数据转换为Java对象。
请求体只能被读取一次:HTTP请求体是一个输入流,它只能被读取一次。一旦HttpMessageConverter读取了请求体,输入流就被“消耗”掉了,无法再次被读取。因此,当切面尝试访问请求体时,它发现输入流已经为空或不可用。
解决方法:
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;public class CachedBodyHttpServletRequestWrapper extends HttpServletRequestWrapper {private final byte[] cachedBody;public CachedBodyHttpServletRequestWrapper(HttpServletRequest request) throws IOException {super(request);ByteArrayOutputStream outputStream = new ByteArrayOutputStream();InputStream inputStream = request.getInputStream();byte[] buffer = new byte[1024];int bytesRead;while ((bytesRead = inputStream.read(buffer)) != -1) {outputStream.write(buffer, 0, bytesRead);}cachedBody = outputStream.toByteArray();}@Overridepublic ServletInputStream getInputStream() throws IOException {final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(cachedBody);return new ServletInputStream() {@Overridepublic boolean isFinished() {return byteArrayInputStream.available() == 0;}@Overridepublic boolean isReady() {return true;}@Overridepublic void setReadListener(ReadListener readListener) {}@Overridepublic int read() throws IOException {return byteArrayInputStream.read();}};}public String getCachedBody() {return new String(cachedBody, StandardCharsets.UTF_8);}
}
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;public class CachedBodyFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {if (request instanceof HttpServletRequest) {HttpServletRequest httpRequest = (HttpServletRequest) request;CachedBodyHttpServletRequestWrapper cachedBodyRequestWrapper = new CachedBodyHttpServletRequestWrapper(httpRequest);chain.doFilter(cachedBodyRequestWrapper, response);} else {chain.doFilter(request, response);}}@Overridepublic void destroy() {}
}
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class FilterConfig {@Beanpublic FilterRegistrationBean<CachedBodyFilter> loggingFilter(){FilterRegistrationBean<CachedBodyFilter> registrationBean = new FilterRegistrationBean<>();registrationBean.setFilter(new CachedBodyFilter());registrationBean.addUrlPatterns("/*");return registrationBean; }
}
然后在切面里利用CachedBodyHttpServletRequestWrapper 去获取requestBody就可以了。
相关文章:
使用AOP在切面逻辑中无法获取到requesetBody
使用场景:在接口处理之前,我们需要拿到请求参数,对参数进行校验。注意,这里需要拿到的是原始的请求信息! 一般的获取方式 ServletInputStream inputStream request.getInputStream(); StringBuilder stringBuilder …...
生成模型:变分自编码器-VAE
1.基本概念 1.1 概率 这里有: x为真实图像,开源为数据集, 编码器将其编码为分布参数 x ^ \hat{x} x^为生成图像, 通过解码器获得 p ( x ) ^ \hat{p(x)} p(x)^: 观测数据的分布, 即数据集所构成的经验分布 p r e a l ( x ) p_{real}(x) preal(x): …...
Hive sql执行文件合并配置参数
HIVE自动合并输出的小文件的主要优化手段为:HIVE将会启动一个独立的map-reduce任务进行输出文件的merge。 set hive.merge.mapfiles true: 在只有map的作业结束时合并小文件, set hive.merge.mapredfiles true: 在Map-Reduce的任…...
鸿蒙 ArkUI实现地图找房效果
常用的地图找房功能,是在地图上添加区域、商圈、房源等一些自定义 marker,然后配上自己应用的一些筛选逻辑构成,在这里使用鸿蒙 ArkUI 简单实现下怎么添加区域/商圈、房源等 Marker. 1、开启地图服务 在华为开发者官网,注册应用&…...
一套极简易的直流无刷电机(Deng FOC)开发套件介绍
目录 概述 1. 硬件组成介绍 1.1 主要硬件 1.2 电机驱动板介绍 1.3 2208电机模块 1.3.1 参数介绍 1.3.2 认识2208电机 2 驱动板接口介绍 2.1 PCB接口(MCU)定义 2.2 功能描述 2.2.1 电机驱动接口 2.2.2 编码器接口 2.2.3 电流输入引脚接口 2.…...
Inception模型详解及代码分析
模型背景 Inception系列模型由Google团队提出,旨在解决CNN分类模型面临的两大挑战: 如何在增加网络深度的同时提升分类性能 如何在保证分类准确率的同时降低计算和内存开销 Inception V1通过引入 并行卷积结构 和 1x1卷积 ,巧妙地解决了这两个问题,在保证模型质量的前提下…...
Springboot AOP 每个接口运行前 修改入参
控制台log输出为何频频失踪? wxss代码为何频频失效? wxml布局为何乱作一团? 究竟是道德的沦丧?还是人性的缺失? 让我们一起来 走 跑进科学 前言 麻蛋被这个功能恶心好久 终于解决了 特此记录一下 正文 Before("authCut()")public void cutProc…...
课题推荐——基于GPS的无人机自主着陆系统设计
关于“基于GPS的无人机自主着陆系统设计”的详细展开,包括项目背景、具体内容、实施步骤和创新点。如需帮助,或有导航、定位滤波相关的代码定制需求,请点击文末卡片联系作者 文章目录 项目背景具体内容实施步骤相关例程MATLAB例程python例程 …...
【深度学习】在深度学习训练过程中,数据量太少会导致模型过拟合还是欠拟合?
过拟合与欠拟合 过拟合 : 是指在训练集上表现非常好,但是在新的数据集上表现较差的现象。具体来说,模型在训练集上过度学习,捕捉了数据中的噪声和偶然性,导致它对训练数据的拟合非常精确,但缺乏泛化能力,无…...
js迭代器模式
以前JS原生的集合类型数据结构,只有Array(数组)和Object(对象); 而ES6中,又新增了Map和Set。四种数据结构各自有着自己特别的内部实现,但我们仍期待以同样的一套规则去遍历它们&…...
测试开发基础知识2
10.什么是等价类和边界值法? 1)等价类划分 等价类划分是将系统的输入域划分为若干部分,然后从每个部分选取少量代表性数据进行测试。等价类划分认为如果一个测试用例在某个等价类中的一个值上通过测试,那么它在这个类中的其他值上也…...
PromQL基础使用和案例解析
文章目录 PromQL简介数据类型1、瞬时数据 (Instant vector)2、区间数据 (Range vector)➢ Time Durations➢ Offest modifier➢ modifier 3、标量数据 (Scalar)4、字符串 (String) 条件匹配1、完全匹配2、正则匹配 运算符1、比较运算符2、算数运算符3、逻辑运算符4、聚合运算符…...
使用Python实现基于机器学习的垃圾邮件过滤
友们好! 我的新专栏《Python进阶》正式启动啦!这是一个专为那些渴望提升Python技能的朋友们量身打造的专栏,无论你是已经有一定基础的开发者,还是希望深入挖掘Python潜力的爱好者,这里都将是你不可错过的宝藏。 在这个专栏中,你将会找到: ● 深入解析:每一篇文章都将深…...
MySql根据经纬度查询距离
一、搭建测试 创建数据表() CREATE TABLE sys_test (id int(11) NOT NULL AUTO_INCREMENT COMMENT 主键ID,name varchar(20) DEFAULT NULL COMMENT 名称,longitude decimal(10,6) DEFAULT NULL COMMENT 经度,latitude decimal(10,6) DEFAULT NULL COMMENT 维度,PRIMARY KEY (id…...
Aviatrix Controller 未授权命令注入漏洞复现(CVE-2024-50603)
0x01 产品简介 Aviatrix Controller是一款强大的云网络管理平台,提供简化的跨云网络管理、自动化配置、安全策略、流量监控等功能,帮助企业实现更加灵活、安全和高效的云网络架构,特别适用于多云和混合云环境。主要用于编排和管理各种网络和连接解决方案。它为用户提供了一…...
数据结构与算法之二叉树: LeetCode 109. 有序链表转换二叉搜索树 (Ts版)
有序链表转换二叉搜索树 https://leetcode.cn/problems/convert-sorted-list-to-binary-search-tree/description/ 描述 给定一个单链表的头节点 head ,其中的元素 按升序排序 ,将其转换为 平衡 二叉搜索树 示例 1 输入: head [-10,-3,0,5,9] 输出:…...
Android NDK开发入门2之适应idm环境
环境搭建 Android NDK开发实战之环境搭建篇(so库,Gemini ai)-CSDN博客 初始配置 前面已经运行了一个简单的初始程序,现在我们来往初始程序添加类和函数,并成功运行的实验。 一级配置 第一层配置主要是cmake文件环境和一些编译选项。 build配置 可参…...
如何隐藏 Nginx 版本号 并自定义服务器信息,提升安全性
🏡作者主页:点击! Nginx-从零开始的服务器之旅专栏:点击! 🐧Linux高级管理防护和群集专栏:点击!点击!点击! ⏰️创作时间:2025年1月8日8点14分…...
鸿蒙的APP真机调试以及发布
目录: 1、创建好鸿蒙项目2、创建AGC项目3、实现自动签名3.1、手动方式创建签名文件和密码 4、运行项目5、无线真机调试 1、创建好鸿蒙项目 2、创建AGC项目 (1)在File->Project Structure->Project->Signing Configs中进行登录。(未…...
图像处理|膨胀操作
在图像处理领域,形态学操作是一种基于图像形状的操作,用于分析和处理图像中对象的几何结构。**膨胀操作(Dilation)**是形态学操作的一种,它能够扩展图像中白色区域(前景)或减少黑色区域…...
FISCO BCOS 多方协作治理组件
组件定位 区块链历经10余年的发展,基础技术框架逐渐完善,链上承载的业务越来越丰富,参与方越来越多。多方协作能否顺畅进行、业务摩擦能否得到有效解决、既往治理策略和实践能否满足日后高速发展的需求……行业关注的重点逐步聚焦到这些更具挑战性的难题上。 2021年1月,微…...
G-Helper:彻底告别华硕Armoury Crate臃肿与卡顿的轻量级解决方案
G-Helper:彻底告别华硕Armoury Crate臃肿与卡顿的轻量级解决方案 【免费下载链接】g-helper Lightweight, open-source control tool for ASUS laptops and ROG Ally. Manage performance modes, fans, GPU, battery, and RGB lighting across Zephyrus, Flow, TUF,…...
JavaScript 同步异步机制和 Promise 原理实现笔记
题目描述 如何实现一个函数对象满足给出的含异步操作且严格限制调用顺序的链式函数调用过程? arrange(aaa).wait(5).do(commit).waitFirst(3).execute(); // wait 和 waitFirst 是异步操作 // 要求输出为:start -> output `wait 5s` -> output `commit` -> output…...
别再写错Verilog三态门了!一个assign语句搞定FPGA双向IO(附仿真避坑指南)
Verilog三态门实战指南:从代码误区到仿真验证 双向IO设计是FPGA开发中绕不开的经典问题,而三态门作为实现双向传输的核心元件,其代码写法看似简单却暗藏玄机。不少工程师在项目后期才发现三态门行为异常,仿真结果与预期不符&#…...
Fish Speech 1.5可部署方案:私有化语音合成服务搭建完整指南
Fish Speech 1.5可部署方案:私有化语音合成服务搭建完整指南 1. 项目概述与核心价值 Fish Speech 1.5是一个基于VQ-GAN和Llama架构的先进文本转语音模型,经过超过100万小时的多语言音频数据训练。这个模型最大的特点是能够提供高质量的语音合成服务&am…...
终极指南:ESLyric-LyricsSource三大逐字歌词格式深度解析与实战部署
终极指南:ESLyric-LyricsSource三大逐字歌词格式深度解析与实战部署 【免费下载链接】ESLyric-LyricsSource Advanced lyrics source for ESLyric in foobar2000 项目地址: https://gitcode.com/gh_mirrors/es/ESLyric-LyricsSource ESLyric-LyricsSource是专…...
LaserGRBL激光雕刻软件:从零开始的完整使用指南
LaserGRBL激光雕刻软件:从零开始的完整使用指南 【免费下载链接】LaserGRBL Laser optimized GUI for GRBL 项目地址: https://gitcode.com/gh_mirrors/la/LaserGRBL LaserGRBL是一款专为GRBL控制器设计的激光雕刻软件,它为激光雕刻爱好者提供了一…...
Pixel Dimension Fissioner 版本管理实战:Git协作开发工作流
Pixel Dimension Fissioner 版本管理实战:Git协作开发工作流 1. 为什么需要版本管理 在团队开发Pixel Dimension Fissioner这类AI项目时,代码、模型配置和Prompt模板的变更非常频繁。没有版本管理就像在走钢丝——一个不小心的修改可能导致整个项目崩溃…...
质数判定的平方根法则对打印质数问题
定理:如果一个数 x,在2~√x都没有能整除它的数,那么x就是质数。证明:对于一个在2~x - 1的数 t,如果它能整除 x,那么一定有一个数d x / t,也能整除 x。又因为d * t x,√x * √x x&…...
研发公司一物一码如何打通产品研发与渠道数字化
研发公司一物一码如何打通产品研发与渠道数字化在快消行业,产品研发、渠道动销与消费者反馈原本应该形成闭环,但多数企业现实中仍是“研发看内部数据,销售看出货数据,市场看活动数据”。当产品从立项到铺市缺少统一的数据连接&…...
