@ModelAttribute vs @RequestBody

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


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

作用

  • 在 @Controller 或 @RequestMapping 方法执行前 自动调用,用于将请求参数(query params、form data、JSON 等)绑定到一个 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. 将表单中的 username 和 password 绑定到 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/user,Content-Type: application/x-www-form-urlencoded):

    复制代码
    复制代码
    `username=John&password=123456`
  • 或 (POST /api/user,Content-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 对象,并绑定请求参数(如 username、password)。
    • 相当于隐式调用了 @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 使用。

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

相关推荐
ZealSinger2 小时前
Java虚拟线程上线后瓶颈转移到哪看三层
java·开发语言·firefox
2601_961133282 小时前
盘立方软件指标文华期货公式下载
java
蜗牛互联网2 小时前
长任务多Agent共享文件系统的Manifest交接模式
java·人工智能·后端
Sirens.2 小时前
Java并发锁详解:六类锁策略与 synchronized 底层原理
java·前端·算法
sunshine22 girl3 小时前
Java学习五 面向对象高级5 内部类1
java·学习
用户1305180712154 小时前
JDBC学习DAY2:从Statement到PreparedStatement
java
蛋蛋的就会顺顺的5 小时前
hot100——矩阵
java·数据结构·算法·leetcode·力扣
周杰偷奶茶5 小时前
【Java】数组的定义和使用(附管理系统实战案例)
java·开发语言
橙子圆1236 小时前
JUC之集合类不安全
java·开发语言
谢亮_vipxieliang7 小时前
Stream API 不是银弹:常见坑与性能建议
java·开发语言