@ModelAttribute vs @RequestBody

@ModelAttributeSpring MVC 中的一个核心注解,主要用于在控制器(@Controller@RestController)中处理 HTTP 请求参数绑定到 Java 对象 ,以及 向视图(如 JSP、Thymeleaf)或响应体中添加模型数据。它有两种主要用法:


1. 方法级 @ModelAttribute(绑定请求参数到对象)

作用

  • @Controller@RequestMapping 方法执行前 自动调用,用于将请求参数(query paramsform dataJSON 等)绑定到一个 Java 对象(通常是 POJO)。
  • 绑定后的对象会被自动添加到 Model 中,供视图(如 JSP、Thymeleaf)或后续方法使用。

示例

场景 1:表单提交(application/x-www-form-urlencoded
复制代码

java

复制代码
`@Controller
public class UserController {
    // 方法级 @ModelAttribute:在 @PostMapping 方法执行前自动调用
    @ModelAttribute("user")  // 可选:指定 Model 中的 key(默认是类名首字母小写,如 "user")
    public User prepareUser() {
        return new User(); // 返回一个空对象,Spring 会自动填充请求参数
    }

    @PostMapping("/register")
    public String register(@ModelAttribute("user") User user, BindingResult result) {
        if (result.hasErrors()) {
            return "error"; // 返回错误页面
        }
        return "success"; // 返回成功页面
    }
}`
  • 请求示例 (表单提交):

    复制代码

    html

    复制代码
    `<form action="/register" method="post">
        <input type="text" name="username" placeholder="用户名">
        <input type="password" name="password" placeholder="密码">
        <button type="submit">注册</button>
    </form>`
  • Spring 会自动

    1. 调用 prepareUser() 创建 User 对象。
    2. 将表单中的 usernamepassword 绑定到 User 对象的对应字段。
    3. User 对象存入 Model(key 默认为 "user")。
    4. register() 方法中可以直接使用绑定后的 User 对象。

场景 2:REST API(application/json

如果请求是 JSON 格式(@RestController@RequestBody 不适用时),可以手动绑定:

复制代码

java

复制代码
`@PostMapping("/api/user")
public ResponseEntity<User> createUser(@ModelAttribute User user) {
    return ResponseEntity.ok(user); // 返回绑定后的 User 对象
}`
  • 请求示例POST /api/userContent-Type: application/x-www-form-urlencoded):

    复制代码
    复制代码
    `username=John&password=123456`
  • POST /api/userContent-Type: application/json,需额外配置):

    复制代码

    json

    复制代码
    `{
        "username": "John",
        "password": "123456"
    }`

    注意@ModelAttribute 默认不支持 JSON,通常用 @RequestBody 处理 JSON 请求。


2. 参数级 @ModelAttribute(直接绑定请求参数到方法参数)

作用

  • 直接在方法参数上使用 @ModelAttribute,Spring 会自动从请求中绑定数据到该对象。
  • 适用于 简化代码 ,避免显式调用 @ModelAttribute 方法。

示例

复制代码

java

复制代码
`@PostMapping("/register")
public String register(@ModelAttribute User user, BindingResult result) {
    if (result.hasErrors()) {
        return "error";
    }
    return "success";
}`
  • 效果
    • Spring 会自动创建一个 User 对象,并绑定请求参数(如 usernamepassword)。
    • 相当于隐式调用了 @ModelAttribute 方法。

3. @ModelAttribute 的其他用途

(1) 向 Model 中添加数据(不绑定请求参数)

复制代码

java

复制代码
`@ModelAttribute("message")
public String addMessage() {
    return "Hello, Spring MVC!";
}`
  • 作用
    • "Hello, Spring MVC!" 添加到 Model 中,key 为 "message"
    • 可以在视图(如 JSP、Thymeleaf)中直接使用 ${message}

(2) 与 @SessionAttributes 结合使用

复制代码

java

复制代码
`@Controller
@SessionAttributes("user") // 将 Model 中的 "user" 存入 Session
public class UserController {
    @ModelAttribute("user")
    public User prepareUser() {
        return new User();
    }

    @PostMapping("/login")
    public String login(@ModelAttribute("user") User user) {
        // 登录逻辑...
        return "redirect:/dashboard"; // 跳转后,user 仍存在于 Session
    }
}`
  • 作用
    • Model 中的 user 对象存入 HttpSession,后续请求可以继续使用。

@ModelAttribute vs @RequestBody

特性 @ModelAttribute @RequestBody
数据来源 表单数据(application/x-www-form-urlencoded JSON/XML(application/json
绑定方式 自动绑定请求参数到 Java 对象字段 通过 HttpMessageConverter 反序列化
适用场景 传统表单提交、REST API(非 JSON) REST API(JSON/XML)
校验支持 支持 @Valid 支持 @Valid

示例对比

@ModelAttribute(表单提交)
复制代码

java

复制代码
`@PostMapping("/user")
public String createUser(@ModelAttribute User user) {
    return "user: " + user.getUsername();
}`
  • 请求

    复制代码
    复制代码
    `POST /user
    Content-Type: application/x-www-form-urlencoded
    username=John&password=123`
@RequestBody(JSON 请求)
复制代码

java

复制代码
`@PostMapping("/api/user")
public ResponseEntity<User> createUser(@RequestBody User user) {
    return ResponseEntity.ok(user);
}`
  • 请求

    复制代码
    复制代码
    `POST /api/user
    Content-Type: application/json
    {
        "username": "John",
        "password": "123"
    }`

总结

用法 说明
方法级 @ModelAttribute @RequestMapping 方法前执行,绑定请求参数到对象并存入 Model
参数级 @ModelAttribute 直接绑定请求参数到方法参数对象
Model 添加数据 @ModelAttribute("key") String value()
@SessionAttributes 结合 Model 数据存入 Session
适用场景 表单提交、非 JSON REST API

最佳实践

  1. 表单提交 → 用 @ModelAttribute
  2. JSON/XML REST API → 用 @RequestBody
  3. 校验 → 结合 @Valid@Validated 使用。

希望这个解释能帮到你! 😊

相关推荐
草履虫建模15 小时前
力扣算法 1768. 交替合并字符串
java·开发语言·算法·leetcode·职场和发展·idea·基础
qq_2975746717 小时前
【实战教程】SpringBoot 实现多文件批量下载并打包为 ZIP 压缩包
java·spring boot·后端
老毛肚17 小时前
MyBatis插件原理及Spring集成
java·spring·mybatis
学嵌入式的小杨同学17 小时前
【Linux 封神之路】信号编程全解析:从信号基础到 MP3 播放器实战(含核心 API 与避坑指南)
java·linux·c语言·开发语言·vscode·vim·ux
lang2015092817 小时前
JSR-340 :高性能Web开发新标准
java·前端·servlet
Re.不晚18 小时前
Java入门17——异常
java·开发语言
缘空如是18 小时前
基础工具包之JSON 工厂类
java·json·json切换
追逐梦想的张小年18 小时前
JUC编程04
java·idea
好家伙VCC18 小时前
### WebRTC技术:实时通信的革新与实现####webRTC(Web Real-TimeComm
java·前端·python·webrtc
南极星100519 小时前
蓝桥杯JAVA--启蒙之路(十)class版本 模块
java·开发语言