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

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

相关推荐
码路飞4 小时前
GPT-5.3 Instant 终于学会好好说话了,顺手对比了下同天发布的 Gemini 3.1 Flash-Lite
java·javascript
SimonKing4 小时前
OpenCode AI编程助手如何添加Skills,优化项目!
java·后端·程序员
Seven976 小时前
剑指offer-80、⼆叉树中和为某⼀值的路径(二)
java
怒放吧德德17 小时前
Netty 4.2 入门指南:从概念到第一个程序
java·后端·netty
雨中飘荡的记忆19 小时前
大流量下库存扣减的数据库瓶颈:Redis分片缓存解决方案
java·redis·后端
心之语歌21 小时前
基于注解+拦截器的API动态路由实现方案
java·后端
华仔啊1 天前
Stream 代码越写越难看?JDFrame 让 Java 逻辑回归优雅
java·后端
ray_liang1 天前
用六边形架构与整洁架构对比是伪命题?
java·架构
Ray Liang1 天前
用六边形架构与整洁架构对比是伪命题?
java·python·c#·架构设计
Java水解1 天前
Java 中间件:Dubbo 服务降级(Mock 机制)
java·后端