@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 使用。

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

相关推荐
雨中飘荡的记忆2 小时前
深度详解Spring Context
java·spring
Tao____2 小时前
JAVA开源物联网平台
java·物联网·mqtt·开源·ruoyi
yqd6662 小时前
SpringSecurity的使用
java·spring
仙俊红3 小时前
Java Map 家族核心解析
java·开发语言
一嘴一个橘子3 小时前
springMvc 接收参数、cookie、header
java
code_li4 小时前
聊聊支付宝架构
java·开发语言·架构
CC.GG4 小时前
【Linux】进程概念(五)(虚拟地址空间----建立宏观认知)
java·linux·运维
以太浮标5 小时前
华为eNSP模拟器综合实验之- AC+AP无线网络调优与高密场景
java·服务器·华为
Mr__Miss5 小时前
JAVA面试-框架篇
java·spring·面试