Spring MVC @RequestBody 注解怎么用?接收什么格式的数据?
@RequestBody
注解的作用
@RequestBody
将方法上的参数绑定到 HTTP 请求的 Body(请求体)的内容上。
当客户端发送一个包含数据的请求体(通常在 POST
, PUT
, PATCH
请求中)时,@RequestBody
告诉 Spring MVC 读取这个请求体,并使用已注册的 HttpMessageConverter
将其内容**反序列化(Deserialize)**为一个 Java 对象。
简单来说,它允许我们直接将请求中发送的 JSON、XML 或其他格式的数据映射到一个 Java 对象(通常是一个 POJO - Plain Old Java Object)。
@RequestBody
的工作机制
- 读取请求体: Spring MVC 获取 HTTP 请求的输入流。
- 检查
Content-Type
Header: 查看请求头中的Content-Type
,例如application/json
或application/xml
。这个 Header 会告诉服务器客户端发送的是什么格式的数据。 - 选择
HttpMessageConverter
: Spring MVC 会查找已注册的、能够处理该Content-Type
的请求体内容转换为方法参数指定类型的HttpMessageConverter
。 - 反序列化:
HttpMessageConverter
读取请求体内容,并将其转换为目标 Java 对象。 - 参数绑定: 转换后的 Java 对象会传递给带有
@RequestBody
注解的方法参数。
常用场景:接收 JSON 或 XML 数据
@RequestBody
最常用于接收客户端发送的 JSON 或 XML 数据,尤其是在构建 RESTful API 时。
示例:接收 JSON 数据
假设客户端发送一个 POST
请求到 /api/users
,请求体包含以下 JSON 数据:
{"username": "john.doe","email": "john.doe@example.com","age": 30
}
并且请求头中设置了 Content-Type: application/json
。
我们可以定义一个对应的 Java POJO:
// User.java (POJO)
public class User {private String username;private String email;private int age;// Getters and Setters (必需,供 Jackson 等库使用)public String getUsername() { return username; }public void setUsername(String username) { this.username = username; }public String getEmail() { return email; }public void setEmail(String email) { this.email = email; }public int getAge() { return age; }public void setAge(int age) { this.age = age; }@Overridepublic String toString() {return "User{" +"username='" + username + '\'' +", email='" + email + '\'' +", age=" + age +'}';}
}
然后在 Controller 中这样使用 @RequestBody
:
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpStatus;@RestController
@RequestMapping("/api/users")
public class UserController {@PostMappingpublic ResponseEntity<String> createUser(@RequestBody User user) {// 此时,Spring MVC 已经使用 HttpMessageConverter (通常是 Jackson)// 将请求体中的 JSON 数据转换为了一个 User 对象实例 'user'System.out.println("Received user: " + user);// 在这里可以进行保存用户等业务逻辑...// userService.save(user);return ResponseEntity.status(HttpStatus.CREATED).body("User created successfully: " + user.getUsername());}
}
所需依赖
Spring MVC 依赖 HttpMessageConverter
来实现 @RequestBody
的功能。
-
处理 JSON (最常用):
- 依赖库: Jackson Databind (
jackson-databind
) 是 Spring Boot 和 Spring MVC 处理 JSON 的默认库。 - 如何添加: 如果使用 Spring Boot,
spring-boot-starter-web
starter 会自动包含jackson-databind
。通常不需要手动添加它。 - Maven 示例 (如果未使用 Spring Boot Starter 或需要特定版本):
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><!-- <version>...</version> --> <!-- Spring Boot 管理版本 --> </dependency>
- 替代库: 虽然不常用,但也可以配置使用其他 JSON 库,如 Gson (
com.google.code.gson:gson
) 或 JSON-B。
- 依赖库: Jackson Databind (
-
处理 XML:
- 依赖库:
- JAXB (Java Architecture for XML Binding): 这是 Java 标准库的一部分(直到 Java 10,Java 11 及以后需要单独添加依赖)。Spring 对 JAXB 有内建支持。
- Jackson XML extension (
jackson-dataformat-xml
): 这是 Jackson 提供的用于处理 XML 的模块,与处理 JSON 的方式非常相似,通常更受欢迎,因为它与 Jackson 的其他功能(如注解)集成得更好。
- 如何添加 (Jackson XML): 如果你想使用 Jackson 处理 XML,需要手动添加
jackson-dataformat-xml
依赖。spring-boot-starter-web
不包含它。 - Maven 示例 (Jackson XML):
<dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-xml</artifactId><!-- <version>...</version> --> <!-- Spring Boot 管理版本 --> </dependency>
- POJO 注解: 如果使用 JAXB 或 Jackson XML,需要在 POJO 上添加特定的注解(如
@XmlRootElement
,@XmlElement
for JAXB,或者 Jackson 也可以使用 JAXB 注解或其自己的注解)映射 XML 结构。不过,对于简单的结构,Jackson XML 也能在没有额外注解的情况下工作。
- 依赖库:
示例:Controller 处理 XML (假设已添加 jackson-dataformat-xml
)
如果客户端发送 Content-Type: application/xml
和以下 XML 请求体:
<User><username>jane.doe</username><email>jane.doe@example.com</email><age>28</age>
</User>
上面的 createUser
方法无需修改(只要 User
POJO 的结构匹配),Spring MVC 会自动选择 MappingJackson2XmlHttpMessageConverter
(如果 jackson-dataformat-xml
在 classpath 中)来处理请求。
关键点和注意事项
Content-Type
Header: 客户端必须发送正确的Content-Type
请求头,以便 Spring MVC 知道如何解析请求体并选择合适的HttpMessageConverter
。如果Content-Type
不匹配或缺失,通常会导致 HTTP 415 (Unsupported Media Type) 错误。- 必需性:
@RequestBody
标注的参数默认是必需的。如果请求体为空或无法转换为目标类型,会抛出HttpMessageNotReadableException
,通常导致 HTTP 400 (Bad Request) 错误。 - 唯一性: 一个 Controller 方法只能有一个参数使用
@RequestBody
注解,因为一个 HTTP 请求只有一个请求体。 - 不要与
@RequestParam
混淆:@RequestParam
用于获取 URL 查询参数或表单数据(application/x-www-form-urlencoded
),而@RequestBody
用于获取整个请求体的内容(通常是 JSON 或 XML)。 - Validation: 通常会结合 Java Bean Validation API (JSR 380/303) 使用
@RequestBody
。通过在@RequestBody
参数前添加@Valid
注解,可以自动触请求体反序列化后的对象的校验。
import javax.validation.Valid;
import javax.validation.constraints.Email;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;// User.java (带校验注解)
public class User {@NotBlank(message = "Username cannot be blank")private String username;@NotBlank@Email(message = "Invalid email format")private String email;@Min(value = 0, message = "Age must be positive")private int age;// ... Getters and Setters ...
}// Controller 方法
@PostMapping
public ResponseEntity<String> createUser(@Valid @RequestBody User user) {// 如果校验失败,Spring 会自动返回 400 Bad Request// 如果校验成功,代码继续执行System.out.println("Received valid user: " + user);// ...return ResponseEntity.status(HttpStatus.CREATED).body("User created successfully: " + user.getUsername());
}
要使 @Valid
生效,需要添加 spring-boot-starter-validation
依赖(如果使用 Spring Boot)或相应的 hibernate-validator
依赖。
总结
@RequestBody
用于将 HTTP 请求的完整 Body 反序列化为一个 Java 对象。- 主要用于接收
POST
,PUT
,PATCH
请求中的 JSON 或 XML 数据。 - 依赖于
HttpMessageConverter
和相应的库(如jackson-databind
for JSON,jackson-dataformat-xml
or JAXB for XML)。 spring-boot-starter-web
默认包含 Jackson JSON 支持。处理 XML 需要手动添加依赖。- 客户端必须发送正确的
Content-Type
Header。 - 一个方法只能有一个
@RequestBody
参数。 - 常与
@Valid
结合进行自动数据校验。
相关文章:
Spring MVC @RequestBody 注解怎么用?接收什么格式的数据?
RequestBody 注解的作用 RequestBody 将方法上的参数绑定到 HTTP 请求的 Body(请求体)的内容上。 当客户端发送一个包含数据的请求体(通常在 POST, PUT, PATCH 请求中)时,RequestBody 告诉 Spring MVC 读取这个请求体…...

第38课 常用快捷操作——双击“鼠标左键”进入Properties Panel
概述 在设计过程中,我们经常需要更改某个图元的属性,例如更该焊盘的大小、更改网络的名称等等。 在AD 20中,更改属性一般都是在Properties Panel上完成的。 当我们要更改某个图元的属性时,我们用鼠标左键双击它,就可…...
【git】获取特定分支和所有分支
1 特定分支 1.1 克隆指定分支(默认只下载该分支) git clone -b <分支名> --single-branch <仓库URL> 示例(克隆 某一个 分支): git clone -b xxxxxx --single-branch xxxxxxx -b :指定分支…...

从零开发一个B站视频数据统计Chrome插件
从零开发一个B站视频数据统计Chrome插件 前言 B站(哔哩哔哩)作为国内最大的弹幕视频网站之一,视频的播放量、点赞、投币、收藏等数据对于内容创作者和数据分析者来说非常重要。本文将带你一步步实现一个Chrome插件,自动统计并展…...
经典算法 石子合并问题
石子合并问题 问题描述 在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分。试设计出一个算法,计算出将N堆石子合并成1堆最大得分和最小得分。 输入描述…...

[stm32] 4-1 USART(1)
文章目录 前言4-2 USART与串口通信(1)USART简介什么是USART?USART名字的含义?如何使用USART? USART的工作原理什么是串并转换?为什么要进行串并转换?移位寄存器串并行转换电路 USART寄存器组和完整框图 前言 本笔记内容ÿ…...
智能家居的OneNet云平台
一、声明 该项目只需要创建一个产品,然后这个产品里面包含几个设备,而不是直接创建几个产品 注意:传输数据使用到了不同的power,还有一定要手机先联网才能使用云平台 二、OneNet云平台创建 (1)Temperatur…...

记录两个免费开源又好用的后台模版vue3
一.element-plus-admin 一套基于vue3、element-plus、typesScript、vite的后台集成方案 1.简介 vue-element-plus-admin 是一个基于 element-plus 免费开源的中后台模版。使用了最新的 Vue3,Vite,Typescript等主流技术开发,开箱即用的中后…...

【AI生产力工具】Windsurf,一款AI编程工具
Windsurf 是 Codeium 公司推出的一款 AI 编程助手,它是一款集成深度上下文感知、多模型协作和实时代码管理的综合开发环境(IDE)。 Windsurf 作为 AI 编程工具的核心价值在于 “上下文感知 + 多模型协作 + 自动化工作流”,其深度集成的智能体系统(如 Flows 和 Cascade)正…...
YOLOv11改进:利用RT-DETR主干网络PPHGNetV2助力轻量化目标检测
这里写自定义目录标题 YOLOv11改进:利用RT-DETR主干网络PPHGNetV2助力轻量化目标检测1. 介绍2. 引言3. 技术背景3.1 YOLOv11概述3.2 RT-DETR与PPHGNetV23.3 相关工作 4. 应用使用场景5. 详细代码实现5.1 环境准备5.2 PPHGNetV2主干网络实现5.3 YOLOv11与PPHGNetV2集…...
Android 端如何监控 ANR、Crash、OOM 等严重问题
在移动互联网时代,Android 应用已经成为我们生活中不可或缺的一部分。从社交聊天到在线购物,从娱乐消遣到办公学习,几乎每个人的手机里都装满了各式各样的应用。然而,作为开发者,咱们得面对一个残酷的现实:用户的耐心是有限的。如果一个应用频繁卡顿、闪退,甚至直接崩掉…...

Mybatisplus:一些常用功能
自动驼峰 mybatis-plus:configuration:# 开启驼峰命名规则,默认true开启map-underscore-to-camel-case: true# 控制台日志打印,便于查看SQLlog-impl: org.apache.ibatis.logging.stdout.StdOutImpl TableName 作用:表名注解,标识…...
oracle 批量查询每张表的数据量
在 Oracle 中批量查询每张表的数据量,可以通过以下两种方法实现。根据数据量大小和实时性要求选择适合的方案: 方法一:通过数据字典快速查询(推荐) 原理: 使用 USER_TABLES(当前用户的表)或 DBA_TABLES(所有表,需DBA权限)中的 NUM_ROWS 字段,该字段记录了表的行数…...
linux netlink实现用户态和内核态数据交互
1,内核态代码 #include <linux/module.h> #include <linux/netlink.h> #include <net/sock.h> #define NETLINK_TEST 31 struct sock *nl_sk NULL; static void nl_recv_msg(struct sk_buff *skb) { struct nlmsghdr *nlh; int pid; …...
java 洛谷题单【算法2-2】常见优化技巧
P1102 A-B 数对 解题思路 输入读取与初始化: 使用 Scanner 读取输入。n 表示数组的长度,c 表示目标差值。使用一个 HashMap 存储数组中每个数字及其出现的次数,方便快速查找。数组 a 用于存储输入的数字。 构建哈希映射: 遍历数…...
WebAPI项目从Newtonsoft.Json迁移到System.Text.Json踩坑备忘
1.控制器层方法返回类型不能为元组 控制器层方法返回类型为元组时,序列化结果为空。 因为元组没有属性只有field,除非使用IncludeFields参数专门指定,否则使用System.Text.Json进行序列化时不会序列化field var options new JsonSerializ…...

batch normalization和layer normalization区别
Normalization无非就是这样一个操作: 其中x是输入数据,维度为(B,T,C),其中B是batchsize,T是序列长度,C是embedding维度;括号内是标准化操作,γ和…...
音视频开发成长之路与音视频知识总结
音视频开发曾经是一个富有挑战性和技术深度的领域。我来分享整理音视频开发的成长路径和知识体系: 音视频开发成长路线图 1. 基础阶段(1-3个月) 计算机基础:C/C、数据结构、操作系统音视频基础概念:采样率、比特率、…...

【多线程】七、POSIX信号量 环形队列的生产者消费者模型
文章目录 Ⅰ. 信号量一、POSIX 信号量的概念二、POSIX 信号量的类型区别三、POSIX 信号量与 SystemV 信号量的区别Ⅱ. 线程信号量基本原理一、为什么要引入信号量❓二、PV 操作三、POSIX 信号量的实现原理四、CAS操作介绍Ⅲ. POSIX未命名信号量接口一、初始化无名信号量二、销毁…...

JVM 一文详解
目录 JVM 简介 JVM 中的内存区域划分 1. 堆(一个进程只有一份 ------ 线程共享) 2. 栈(一个进程可以有 N 份 ------ 线程私有) Java 虚拟机栈: 本机方法栈: 3. 程序计数器(一个线程可以…...
OCR身份证识别(正反面)_个人证照OCR识别_开放API接口使用指南
一、接口简介 在数字化时代,快速准确地提取身份证信息变得尤为重要。**万维易源提供的“身份证OCR识别”API接口,能够快速提取二代居民身份证正反面的所有字段信息,包括姓名、性别、民族、出生日期、住址、身份证号、签发机关、有效期限等。…...
《淘宝 API 数据湖构建:实时商品详情入湖 + Apache Kafka 流式处理指南》
随着电商行业的蓬勃发展,淘宝作为头部电商平台,积累了海量的商品数据。构建淘宝 API 数据湖,将实时商品详情数据纳入其中,并借助 Apache Kafka 进行流式处理,能够为企业提供强大的数据支撑,助力精准营销、市…...
基于ArduinoIDE的任意型号单片机 + GPS北斗BDS卫星定位
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言1.1 器件选择1.2 接线方案 二、驱动实现2.1 核心代码解析(arduino/ESP32-S3) 三、坐标解析代码四、典型问题排查总结 前言 北斗卫星导航…...

代码随想录算法训练营第60期第二十二天打卡
大家好!我们今天来到了一个全新的章节,回溯算法,那究竟什么是回溯算法,我们应该如何理解回溯算法,以及回溯算法可以解决的题目,我们今天就来一探究竟。 第一部分 回溯算法理论基础 其实我可以告诉大家的是…...

自主机器人模拟系统
一、系统概述 本代码实现了一个基于Pygame的2D自主机器人模拟系统,具备以下核心功能: 双模式控制:支持手动控制(WASD键)和自动导航模式(鼠标左键设定目标) 智能路径规划:采用改进型…...

基于QT的仿QQ音乐播放器
一、项目介绍 该项目是基于QT开发的⾳乐播放软件,界面友好,功能丰富,主要功能如下: 窗口hand部分: 点击最小化按钮,窗口最小化 点击最大化按钮,窗口最大化 点击关闭按钮,程序退出 …...

腾讯研究院:《工业大模型应用报告》(文末附下载方式)
腾讯研究院发布的《工业大模型应用报告》是一份系统探讨大模型技术在工业领域落地实践的研究成果。该报告基于腾讯在人工智能、云计算及产业互联网的实践经验,结合国内外典型案例,深入分析了工业大模型的行业价值、关键技术、应用场景及未来趋势。报告指…...
C语言-指针(一)
目录 指针 内存 概念 指针变量 取地址操作符(&) 操作符“ * ” 指针变量的大小 注意 指针类型的意义 作用 void * 指针 const修饰指针变量 const放在*前 const放在*后 双重const修饰 指针的运算 1.指针 - 整数 2.指针 - 指针 3.指…...

【DeepMLF】具有可学习标记的多模态语言模型,用于情感分析中的深度融合
这是一篇我完全看不懂的论文,写的好晦涩,适合唬人,所以在方法部分我以大白话为主 abstract 在多模态情感分析(MSA)中,多模态融合已经得到了广泛的研究,但融合深度和多模态容量分配的作用还没有得到充分的研究。在这项工作中,我们将融合深度、可扩展性和专用多模容量作…...

uniapp如何获取安卓原生的Intent对象
通过第三方app唤起,并且获取第三方app唤起时携带的参数 因为应用a唤起应用b时,应用b第一时间就要拿到参数token,所以需要将获取参数的方法写在APP.vue中的onLaunch钩子里,如果其他地方要用可以选择vuex或者采用本地缓存。 uniapp中plus.run…...