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

@ModelAttribute 和@RequestBody有什么区别

在 Spring 框架的 “参数处理江湖” 中,@ModelAttribute@RequestBody 就像两位风格迥异的 “数据接收专员”—— 前者擅长处理直白的表单信息,后者则专精于解析包裹严密的结构化数据。想要分清它们的 “职责范围”,不妨从日常开发的实际场景入手,一步步揭开它们的差异面纱。

一、核心场景:它们各自 “管什么活儿”?

在开发的 “前线”,两者的分工从一开始就截然不同:

@ModelAttribute 像一位熟稔表单业务的 “前台接待员”,最擅长处理前端通过表单或 URL 直接传递的零散参数。比如用户注册时,前端页面的输入框里填了用户名、密码、邮箱,点击 “提交” 后,这些信息会以 “key=value” 的形式打包(像username=zhangsan&password=123),@ModelAttribute 能一眼认出这些 “平铺直叙” 的参数,自动把它们对应到后端的 User 对象里 —— 用户名参数塞进 user.getUsername(),密码参数放进 user.getPassword(),整个过程就像接待员把访客信息逐条登记到表格里。

@PostMapping("/register")
public String register(@ModelAttribute User user) {// 此时user里已经整整齐齐躺着表单传来的用户名、密码等信息userService.register(user);return "success";
}

@RequestBody 更像一位 “快递分拣员”,专门处理那些被精心打包在 “快递盒”(请求体)里的结构化数据。当前端需要传递复杂信息(比如包含嵌套对象的用户资料:{ "name": "张三", "address": { "city": "北京", "street": "长安街" } }),会用 JSON 或 XML 把数据层层包裹,再贴上 “Content-Type: application/json” 的 “快递单”。@RequestBody 看到这张单子,就知道要拆开请求体,把里面的 JSON 字符串 “还原” 成对应的 Java 对象,就像分拣员根据快递单把包裹里的物品按类别摆好。

@PutMapping("/user/update")
public ResponseEntity<String> updateUser(@RequestBody User user) {// user对象里已经包含了JSON解析后的嵌套地址信息userService.update(user);return ResponseEntity.ok("用户信息更新成功");
}

二、数据来源:它们从 “哪里” 取数据?

如果把请求比作一辆 “数据运输车”,两者的 “取材地点” 截然不同:

@ModelAttribute 的 “数据仓库” 很广:车头上的 “路牌”(URL 查询参数,比如?id=1&name=John)、车厢里的 “散装货物”(表单提交的 Form Data)、甚至驾驶室里的 “司机笔记”(请求头),它都能伸手去拿。比如一个 GET 请求 http://example.com/user?id=1&name=John,它能轻松把 id=1name=John 揪出来,绑定到对象的 idname 属性上。

@RequestBody 则很 “专一”,只盯着车厢最里面的 “密封集装箱”(请求体)。不管车头的路牌写了啥、司机笔记记了啥,它都只拆开集装箱,取里面的 “整装货物”—— 毕竟它的专长就是处理这种 “集中打包” 的数据。

三、数据格式:它们 “认哪种” 包装?

不同的 “取材地点”,决定了它们对数据格式的 “偏好”:

@ModelAttribute 喜欢 “简单直白” 的包装。不管是 URL 里的 key1=value1&key2=value2,还是表单里的 “键值对”,只要参数名和对象属性名能对上(比如表单输入框的 name="username" 对应对象的 username 属性),它就能 “对号入座”。这种格式就像超市货架上的商品,每个商品都贴着明确的标签,一眼就能找到对应的位置。

@RequestBody 则要求 “规范包装”。如果 “快递单” 写的是 application/json,里面就必须是 JSON 格式(比如 {"id":1,"name":"John"});如果是 application/xml,就得是 XML 格式(比如 <user><id>1</id><name>John</name></user>)。Spring 会调用 Jackson 等 “翻译工具”,把这些结构化数据 “翻译” 成 Java 对象 —— 就像必须按标准格式填写的快递单,错一个符号都可能导致 “投递失败”。

四、执行时机:它们 “什么时候” 干活?

在控制器的 “工作流程” 中,两者的出场顺序也有讲究:

@ModelAttribute 可能 “提前到岗”。如果控制器里有被 @ModelAttribute 标注的普通方法(不是处理请求的方法),这些方法会像 “餐前准备员” 一样,在所有请求处理方法(比如 @GetMapping@PostMapping 标注的方法)执行前先干活。比如提前从数据库查点基础数据,放进 “模型仓库”,等后续处理方法要用时直接拿。

@RequestBody 则是 “准时上班”。它只在请求处理方法执行的那一刻,才会去解析请求体里的数据 —— 既不提前准备,也不拖延,就像餐厅里的 “现做厨师”,客人点单了才开始烹饪。

五、适用范围:它们 “能在哪” 工作?

两者的 “工作场所” 也有边界:

@ModelAttribute 是 “多面手”,不仅能在控制器的请求处理方法参数上 “站岗”,还能在控制器的普通方法上 “值班”。比如在普通方法上用 @ModelAttribute,可以往模型里塞点全局数据(像网站的导航菜单信息),供所有视图页面调用。

@RequestBody 则是 “专一岗位”,只能在控制器的请求处理方法参数上 “任职”。它的技能点完全围绕 “解析请求体” 展开,离开控制器的请求处理场景,就派不上用场了。

六、实战对比:前端代码 “怎么配合”?

最后,用一个实际场景看看前端该如何 “配合” 这两位专员:

如果后端用 @ModelAttribute 接收查询参数

前端的请求就像 “在地址栏后贴便签”,把参数直接挂在 URL 后面,用 GET 或 POST 都行。比如查询采购计划时:

handleSearch() {// 参数像便签一样贴在URL后:/api/purchase/planApprove?planBegin=2023-01-01&planEnd=2023-12-31...doGet("/api/purchase/planApprove", {planBegin: this.searchForm.planTime[0],planEnd: this.searchForm.planTime[1],status: this.searchForm.status.value,// ...其他参数}).then(resp => {this.purchasePlans = resp.data.data;})
}

如果后端换成 @RequestBody

前端就得把参数 “装进信封”(请求体),用 POST 方法发送,还得告诉后端 “信封里是 JSON”(通过 Content-Type):

handleSearch() {// 参数像信件一样装进信封(请求体),用POST寄出const params = {planBegin: this.searchForm.planTime[0],planEnd: this.searchForm.planTime[1],// ...其他参数};doPost("/api/purchase/planApprove", params) // doPost会自动设置Content-Type为application/json.then(resp => {this.purchasePlans = resp.data.data;})
}

总之,@ModelAttribute@RequestBody 没有 “谁更好”,只有 “谁更合适”:处理表单、URL 参数等 “零散信息”,找 @ModelAttribute;接收 JSON、XML 等 “结构化数据包”,找 @RequestBody。认清它们的 “脾气秉性”,才能在开发中 “对号入座”,让数据传递更顺畅。

http://www.dtcms.com/a/394269.html

相关文章:

  • npm玩转技巧
  • 柔性精密测量技术在小型化载荷微小应变监测方面的应用
  • 命令注入(Command Injection)漏洞学习笔记
  • 268-基于Django的热门游戏榜单数据分析系统
  • C++篇 类和对象(2)万能工具怎么用?
  • MySQL 多实例部署与主从、读写分离配置
  • C++初阶(10)string类
  • 高性能开源 Web 服务器软件--Nginx
  • 软考中级习题与解答——第十章_多媒体技术(2)
  • 【字符串】1.最⻓公共前缀(easy)
  • 新闻源发稿平台推荐,企业形象宣传新闻源收录平台
  • 梯度提升框架深度解析:LightGBM、XGBoost 与 CatBoost
  • Win10服务器远程连接断开后.bat脚本进程中断的全面解决方案
  • Java与Vue构建资产设备全周期管理系统,覆盖采购、入库、使用、维护至报废全流程,支持移动端实时操作与后台智能管理,提供完整源码便于二次开发
  • Spring Boot 3 + MyBatis-Plus + SelectDB整合方案
  • xtuoj 0x05-B Colombian Number
  • elasticsearch8.1.0 中聚合功能的执行链路
  • WindowTop:提升工作效率的窗口管理工具
  • 每天新增1000万条订单,如何选择合适的数据库?
  • LLaVA模型学习-周报十四
  • LwIP 1.4.0 移植到 uCOSII 参考
  • 【LeetCode 每日一题】3541. 找到频率最高的元音和辅音
  • Arithmetics Competition(贪心+排序+前缀和)
  • 运维安全07 ,JumpServer(堡垒机)介绍以及使用
  • 数据结构算法学习:LeetCode热题100-双指针篇(移动零、盛水最多的容器、三数之和、接雨水)
  • 2025年ESWA SCI1区TOP,复杂威胁环境下带偏差采样的多无人机路径规划、候选物评估与路径重构问题,深度解析+性能实测
  • SeaTunnel 迁移 MySQL 数据到 Easysearch 之批量导入(Batch)
  • JavaWeb 课堂笔记 —— 19 SpringBootWeb案例 文件上传
  • 《时空回响--时之鳞》的现代意义与2025年的现实映射
  • Qwen3Next注意力机制详解与实现