@RequestBody注解的使用及源码解析
前言
@RequestBody 注解是我们进行JavaEE开发,最常见的几个注解之一,这篇博文我们以案例和源码相结合,帮助大家更好的了解 @RequestBody 注解
使用案例
1.自定义实体类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {private String username;private String password;@Overridepublic String toString() {return "User{" +"username='" + username + '\'' +", password='" + password + '\'' +'}';}
}
@RestController
@RequestMapping("/request_body")
public class RequestBodyController {@PostMapping("/entity")public String entity(@RequestBody User user) {return user.toString();}}

2.使用 Map 接收
@PostMapping("/map")
public String map(@RequestBody Map<String, User> map) {return map.toString();
}

3.自定义实体类 (复杂对象)
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Complex {private String tag;private List<User> list;private User[] array;private Map<String, User> map;
}
@PostMapping("/complex")
public String complex(@RequestBody Complex complex) {return complex.toString();
}

请求参数
{"tag": "complex","list": [{"username": "anna","password": "123"},{"username": "bob","password": "456"}],"array": [{"username": "cindy","password": "135"},{"username": "david","password": "246"}],"map": {"u1": {"username": "eric","password": "159"},"u2": {"username": "frank","password": "357"}}
}
4.Content-Type 为 application/xml
添加 POM 文件
<dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-xml</artifactId><version>2.16.1</version>
</dependency>
接口方法 (和案例1只有方法名不一样)
@PostMapping("/xml")
public String xml(@RequestBody User user) {return user.toString();
}
请求头设置
将 Content-Type 设置为 application/xml (一般情况下 Content-Type 为 application/json)

传递参数
<User><username>tom</username><password>123</password>
</User>
响应结果

源码解析
InvocableHandlerMethod#getMethodArgumentValues

参数的处理分为两个阶段:
- 判断当前环境中存在的resolvers,是否支持解析当前参数
- 处理参数
判断是否支持解析当前参数


我的环境中存在27个resolvers,通过命名我们大概可以猜测出 RequestResponseBodyMethodProcessor 是处理 @RequestBody 注解的 resolver
RequestResponseBodyMethodProcessor#supportsParameter

即如果参数上存在 @RequestBody 注解,则使用 RequestResponseBodyMethodProcessor 处理参数
RequestResponseBodyMethodProcessor#resolveArgument



RequestResponseBodyMethodProcessor 的 resolveArgument 方法会遍历当前环境中的 HttpMessageConverters,如果存在一个 HttpMessageConverter 的 canRead 方法返回 true,则使用该 HttpMessageConverter 的 read 方法读取数据。
案例1、2、3 的原理其实是一样的,request 的 Content-Type 为 application/json,spring-boot-starter-web 会引入 json 相关依赖,所以默认情况下,SpringMVC 有把 json 对象转换成 key-value 形式数据结构的能力

案例4 我们引用了相关依赖,使得 SpringMVC 有把 xml 对象转换成 key-value 形式数据结构的能力
小结
如果 request 的 Content-Type 为 xxx,并且存在一个 HttpMessageConverter 支持解析 Content-Type 为 xxx 的数据,通过 @RequestBody 注解,就可以将数据绑定到 key-value 形式的数据结构上
扩展:自定义HttpMessageConverter,处理指定 Content-Type 的请求
创建HttpMessageConverter
public class UserTextPlainHttpMessageConverter implements HttpMessageConverter {@Overridepublic boolean canRead(Class clazz, MediaType mediaType) {return clazz == User.class && "text".equals(mediaType.getType()) && "plain".equals(mediaType.getSubtype());}@Overridepublic boolean canWrite(Class clazz, MediaType mediaType) {return false;}@Overridepublic List<MediaType> getSupportedMediaTypes() {return Collections.singletonList(MediaType.TEXT_PLAIN);}@Overridepublic Object read(Class clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {try (InputStream inputStream = inputMessage.getBody();BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {String line;StringBuilder sb = new StringBuilder();while ((line = reader.readLine()) != null) {sb.append(line);}ObjectMapper objectMapper = new ObjectMapper();return objectMapper.readValue(sb.toString(), User.class);} catch (Exception e) {throw new RuntimeException(e);}}@Overridepublic void write(Object o, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {}
}
创建配置类
@Configuration
public class MessageConfig implements WebMvcConfigurer {@Overridepublic void configureMessageConverters(List<HttpMessageConverter<?>> converters) {converters.add(new UserTextPlainHttpMessageConverter());}}
接口方法 (和案例1、4 只有方法名不一样)
@PostMapping("/convert")
public String convert(@RequestBody User user) {return user.toString();
}
Postman设置
Content-Type 设置为 text/plain

body 传参类型为 text

接口响应

相关文章:
@RequestBody注解的使用及源码解析
前言 RequestBody 注解是我们进行JavaEE开发,最常见的几个注解之一,这篇博文我们以案例和源码相结合,帮助大家更好的了解 RequestBody 注解 使用案例 1.自定义实体类 Data NoArgsConstructor AllArgsConstructor public class User {priv…...
linux 服务器数据备份 和 mysql 数据迁移
查看域名ip 查看程序所处文件位置 list open files 1、 lsof -i :port 查看端口获取进程 pid 2、lsof -i pid 1、scp 下载服务器文件到本地 security copy protocol 2、导出服务器 mysql 数据库(表)到本地 mysqldump是MySQL自带的一个实用程序&…...
安防视频监控/云存储/视频汇聚EasyCVR平台播放设备录像不稳定,是什么原因?
安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快,EasyCVR基于云边端一体化架构,具有强大的数据接入、处理及分发能力,可提供7*24小时实时高清视频监控、云端录像、云存储、录像检索与回看、智能告警…...
S32V234平台开发(一)快速使用
快速使用 准备供电复位选择串口通信启动选择显示登陆系统 准备供电 s32v234可以使用两种电源供电 一种是左边电源端子,一种是右边电源适配器(12V 3A) 注意:不要同时使用两种电源同时供电 复位选择 Pressing POR RESET pulls active low EXT_POR signal on S32V2…...
C# 如何防止反编译?C#程序加密混淆保护方法大全
在C#开发中,由于.NET程序集(assemblies)是基于中间语言(Intermediate Language, IL)编译的,这些程序集可以被反编译回接近原始源代码的形式。为了保护代码不被轻易反编译,开发者可以采取以下几种…...
企业数字化转型中的低代码开发平台应用:释放创新潜能
随着信息技术的飞速发展,企业数字化转型已成为行业趋势。在这场转型浪潮中,低代码开发平台以其独特的优势,成为众多企业实现快速迭代、高效创新的得力助手。本文将深入探讨低代码开发平台在企业数字化转型中的应用,以及如何帮助企…...
因为目录问题开通的另外一个网站的美化过程
起 其实也不完全是目录,是查找问题过程中看到别人的界面好好看,而且确实那个目录很吸引我…… 然后我在csdn看了半天,看到一个有目录的我赶紧换上,结果并不能显示。而且把原来黑色模式的给搞没有了——它居然要vip了……所以………...
RedHat运维-Ansible自动化运维基础24-寻找问题常用模块
1. ansible.builtin.uri模块的作用是____________________________; 2. ansible.builtin.uri模块的作用是____________________________; 3. ansible.builtin.uri模块的作用是____________________________; 4. 试着用ansible.builtin.uri模块…...
windows USB 设备驱动开发-USB带宽
本文讨论如何仔细管理 USB 带宽的指导。 每个 USB 客户端驱动程序都有责任最大程度地减少其使用的 USB 带宽,并尽快将未使用的带宽返回到可用带宽池。 在这里,我们认为USB 2.0 的速度是480Mbps、12Mbps、1.5Mbps,这分别对应高速、全速、低速…...
哪有什么「历史的垃圾时间」,有的只是你对自己的不诚实
时间不会服从任何人的管理,它只会自顾自地流逝。— 李笑来《把时间当作朋友》 hi,欢迎来到我的杂货铺。 最近有个概念火了,叫做「历史的垃圾时间」。 看了下相关的文章,大概是在宣扬奥地利派经济学家米赛斯关于历史的一段论述&a…...
全志A527 T527 android13支持usb摄像头
1.前言 我们发现usb摄像头在A527 android13上面并不能正常使用,需要支持相关的摄像头。 2.系统节点查看 我们查看系统是否有相关的节点生成,发现/dev/video相关的节点已经生成了。并没有问题,拔插正常。 3.这里我们需要查看系统层是否支持相关的相机, 我们使用命令进行…...
邦芒贴士:做到这8点工作生活中才能少犯错
我们之所以需要重点关注这些问题,就是为了确保自身利益能够最大化。如果大家在平日活动里能避免犯下这些错误,就会发现自己的工作效率将会大幅提升,更不用提生活也会变得愉快了很多。 大家如果曾经从建立待办事项列表中获得了很多好处的话&a…...
代码随想录算法训练营第7天
454.四数相加 题目链接:454. 四数相加 II - 力扣(LeetCode) 视频/文档链接:代码随想录 (programmercarl.com) 第一想法 遍历数组num1,num2,计算其和出现的数量,放入map集合中,键为和࿰…...
苹果开发者取消自动续费
文档:https://support.apple.com/zh-cn/118428 如果没有找到订阅,那就是账号不对 取消订阅后,就不会自动续费了,如果不放心,可以把付款绑定的方式也取消...
Phospho:LLM应用的文本分析利器
今天向大家介绍phospho文本分析平台,专门为大型语言模型(LLM)应用程序设计。它可以帮助开发者从用户或应用程序的文本消息中检测问题、提取洞见、收集用户反馈,并衡量成功。作为一个开源项目,phospho允许开发者查看和修…...
微深节能 料场堆取料无人操作系统 格雷母线
随着工业自动化的快速发展,料场堆取料作业正逐步向无人化、智能化转型。格雷母线高精度位移检测系统在料场堆取料无人操作系统中的应用,成为这一转型过程中的重要技术突破。本文将详细介绍格雷母线及其在料场堆取料无人操作系统中的应用,并探…...
Invoice OCR
Invoice OCR 发票识别 其他类型ORC: DIPS_YTPC OCR-CSDN博客...
无菌隔离器内操作规范性的验证之气流流型验证-北京中邦兴业
无菌隔离器在制药行业的使用愈加广泛,但已有的研究更多地聚焦于设计布局、物料状态等方面,对人员操作因素的影响方面关注较少。以冻干制剂生产车间为例,设计了一系列合理的无菌隔离器内干预操作,并在操作人员实行干预操作的基础上…...
【YOLOv8系列】(一)YOLOv8介绍:实时目标检测的最新突破
目录 引言 背景与发展历程 YOLOv8架构设计 1. 改进的特征提取网络 2. 多尺度特征融合 3. 新的激活函数 4. Attention机制 模型训练与优化 性能评估 应用案例 目标检测 图像分割 图像分类 姿势估计 旋转框检测(OBB) 优势与挑战 优势&…...
如何视频提取字幕?推荐5款视频字幕提取软件
#7月份我的同事一个个消失了#,这不仅是一个话题标签,更是许多公司面临的现实写照。 在人手紧缺的夏日,如何提高工作效率成为当务之急。特别是对于需要处理视频内容的团队,一款能够快速提取字幕的软件显得尤为重要。 下面&#x…...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...
【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...
【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看
文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...
