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

使用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

使用场景&#xff1a;在接口处理之前&#xff0c;我们需要拿到请求参数&#xff0c;对参数进行校验。注意&#xff0c;这里需要拿到的是原始的请求信息&#xff01; 一般的获取方式 ServletInputStream inputStream request.getInputStream(); StringBuilder stringBuilder …...

生成模型:变分自编码器-VAE

1.基本概念 1.1 概率 这里有&#xff1a; x为真实图像&#xff0c;开源为数据集, 编码器将其编码为分布参数 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自动合并输出的小文件的主要优化手段为&#xff1a;HIVE将会启动一个独立的map-reduce任务进行输出文件的merge。 set hive.merge.mapfiles true&#xff1a; 在只有map的作业结束时合并小文件&#xff0c; set hive.merge.mapredfiles true&#xff1a; 在Map-Reduce的任…...

鸿蒙 ArkUI实现地图找房效果

常用的地图找房功能&#xff0c;是在地图上添加区域、商圈、房源等一些自定义 marker&#xff0c;然后配上自己应用的一些筛选逻辑构成&#xff0c;在这里使用鸿蒙 ArkUI 简单实现下怎么添加区域/商圈、房源等 Marker. 1、开启地图服务 在华为开发者官网&#xff0c;注册应用&…...

一套极简易的直流无刷电机(Deng FOC)开发套件介绍

目录 概述 1. 硬件组成介绍 1.1 主要硬件 1.2 电机驱动板介绍 1.3 2208电机模块 1.3.1 参数介绍 1.3.2 认识2208电机 2 驱动板接口介绍 2.1 PCB接口&#xff08;MCU&#xff09;定义 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的无人机自主着陆系统设计”的详细展开&#xff0c;包括项目背景、具体内容、实施步骤和创新点。如需帮助&#xff0c;或有导航、定位滤波相关的代码定制需求&#xff0c;请点击文末卡片联系作者 文章目录 项目背景具体内容实施步骤相关例程MATLAB例程python例程 …...

【深度学习】在深度学习训练过程中,数据量太少会导致模型过拟合还是欠拟合?

过拟合与欠拟合 过拟合 : 是指在训练集上表现非常好&#xff0c;但是在新的数据集上表现较差的现象。具体来说&#xff0c;模型在训练集上过度学习&#xff0c;捕捉了数据中的噪声和偶然性&#xff0c;导致它对训练数据的拟合非常精确&#xff0c;但缺乏泛化能力&#xff0c;无…...

js迭代器模式

以前JS原生的集合类型数据结构&#xff0c;只有Array&#xff08;数组&#xff09;和Object&#xff08;对象&#xff09;&#xff1b; 而ES6中&#xff0c;又新增了Map和Set。四种数据结构各自有着自己特别的内部实现&#xff0c;但我们仍期待以同样的一套规则去遍历它们&…...

测试开发基础知识2

10.什么是等价类和边界值法&#xff1f; 1)等价类划分 等价类划分是将系统的输入域划分为若干部分&#xff0c;然后从每个部分选取少量代表性数据进行测试。等价类划分认为如果一个测试用例在某个等价类中的一个值上通过测试&#xff0c;那么它在这个类中的其他值上也…...

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 &#xff0c;其中的元素 按升序排序 &#xff0c;将其转换为 平衡 二叉搜索树 示例 1 输入: head [-10,-3,0,5,9] 输出:…...

Android NDK开发入门2之适应idm环境

环境搭建 Android NDK开发实战之环境搭建篇(so库,Gemini ai)-CSDN博客 初始配置 前面已经运行了一个简单的初始程序&#xff0c;现在我们来往初始程序添加类和函数&#xff0c;并成功运行的实验。 一级配置 第一层配置主要是cmake文件环境和一些编译选项。 build配置 可参…...

如何隐藏 Nginx 版本号 并自定义服务器信息,提升安全性

&#x1f3e1;作者主页&#xff1a;点击&#xff01; Nginx-从零开始的服务器之旅专栏&#xff1a;点击&#xff01; &#x1f427;Linux高级管理防护和群集专栏&#xff1a;点击&#xff01;点击&#xff01;点击&#xff01; ⏰️创作时间&#xff1a;2025年1月8日8点14分…...

鸿蒙的APP真机调试以及发布

目录&#xff1a; 1、创建好鸿蒙项目2、创建AGC项目3、实现自动签名3.1、手动方式创建签名文件和密码 4、运行项目5、无线真机调试 1、创建好鸿蒙项目 2、创建AGC项目 &#xff08;1&#xff09;在File->Project Structure->Project->Signing Configs中进行登录。(未…...

图像处理|膨胀操作

在图像处理领域&#xff0c;形态学操作是一种基于图像形状的操作&#xff0c;用于分析和处理图像中对象的几何结构。**膨胀操作&#xff08;Dilation&#xff09;**是形态学操作的一种&#xff0c;它能够扩展图像中白色区域&#xff08;前景&#xff09;或减少黑色区域&#xf…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

使用VSCode开发Django指南

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

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作&#xff0c;无需更改相机配置。但是&#xff0c;一…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

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 …...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

Mysql8 忘记密码重置,以及问题解决

1.使用免密登录 找到配置MySQL文件&#xff0c;我的文件路径是/etc/mysql/my.cnf&#xff0c;有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...

基于IDIG-GAN的小样本电机轴承故障诊断

目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) ​梯度归一化(Gradient Normalization)​​ (2) ​判别器梯度间隙正则化(Discriminator Gradient Gap Regularization)​​ (3) ​自注意力机制(Self-Attention)​​ 3. 完整损失函数 二…...

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

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

阿里云Ubuntu 22.04 64位搭建Flask流程(亲测)

cd /home 进入home盘 安装虚拟环境&#xff1a; 1、安装virtualenv pip install virtualenv 2.创建新的虚拟环境&#xff1a; virtualenv myenv 3、激活虚拟环境&#xff08;激活环境可以在当前环境下安装包&#xff09; source myenv/bin/activate 此时&#xff0c;终端…...