Spring学习笔记_41——@RequestBody
Spring学习笔记_42——@CookieValue
Spring学习笔记_43——@ExceptionHandler
@ModelAttribute
1. 介绍
@ModelAttribute
是 Spring MVC 框架中的一个注解,用于在控制器(Controller)中处理方法参数或返回值。这个注解可以将请求参数(Request Parameters)或者路径变量(Path Variables)绑定到模型(Model)中的对象,或者直接将对象添加到模型中。它对于构建表单处理、数据预填充等场景非常有用。
2. 场景
在基于SpringMVC或者SpringBoot开发Web应用程序时,如果需要在控制器方法执行之间执行一些方法,处理一些数据逻辑,然后将数据存储到诸如Model、Map和ModelMap等数据结构中。随后在控制器方法中自动获取之间存储的数据,并将其绑定到方法的参数上,此时就可以使用@ModelAttribute注解
- 绑定请求参数到方法参数:
- 当一个方法的参数上使用了
@ModelAttribute
注解时,Spring 将会尝试从请求中获取相应的数据来填充这个参数代表的对象。例如,如果有一个表单提交,Spring 可以自动将表单字段映射到一个 Java 对象的属性上。
- 当一个方法的参数上使用了
- 将对象添加到模型:
- 如果一个方法上使用了
@ModelAttribute
注解,并且该方法返回了一个对象,那么这个对象将会被添加到模型中。这通常用于在渲染视图之前向模型添加数据。
- 如果一个方法上使用了
- 数据预处理:
- 在处理 GET 请求时,可以通过
@ModelAttribute
预填充表单的数据。这对于编辑现有记录的场景特别有用。
- 在处理 GET 请求时,可以通过
3. 源码
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Reflective
public @interface ModelAttribute {// String类型属性// 如果注解标注到方法上,表示存入数据时的Key、存入数据的值时方法的返回值。// 如果注解标注到参数上,则可以从Model、Map或ModelMap等数据结果中获取数据,此时表示获取的数据的Key@AliasFor("name")String value() default "";// 从Spring4.3版本开始提供的String类型的属性,作用与value属性相同@AliasFor("value")String name() default "";// 从Spring4.3版本开始提供的Boolean类型的属性// 表示是否支持绑定数据// true 支持// false 不支持// 默认是trueboolean binding() defalult true;}
4. Demo
4.1 绑定请求参数到模型对象
当你在控制器方法参数前使用 @ModelAttribute 注解时,Spring MVC 会自动将请求参数绑定到该参数所声明的对象上。这通常用于处理表单提交或 GET 请求参数。
示例:
@Controller
public class UserController {// 使用 @ModelAttribute 注解将请求参数绑定到 User 对象@PostMapping("/saveUser")public String saveUser(@ModelAttribute("user") User user) {// 处理 user 对象// 比如保存到数据库return "success";}
}
在这个例子中,@ModelAttribute(“user”) 注解告诉 Spring MVC 将请求参数绑定到 User 类型的 user 对象上。user 对象的属性名和请求参数名必须匹配,才能正确绑定。
4.2 添加模型属性
@ModelAttribute 也可以用在控制器方法上,以便在方法执行后将返回值添加到模型中。这常用于添加全局数据,比如菜单、用户信息等,这些数据在多个视图中都可能需要。
示例:
@Controller
public class CommonController {// 使用 @ModelAttribute 注解添加模型属性@ModelAttribute("currentUser")public User addCurrentUser() {// 从某个地方获取当前用户信息User currentUser = new User();currentUser.setName("John Doe");return currentUser;}
}
在这个例子中,@ModelAttribute(“currentUser”) 注解的方法 addCurrentUser 会在每个控制器方法执行之前被调用,并将返回的 User 对象添加到模型中,模型属性名为 currentUser。这意味着,currentUser 可以在所有视图模板中访问。
4.3 在方法参数和返回值中的组合使用
有时,你可能需要在同一个控制器中同时使用 @ModelAttribute 注解绑定请求参数和添加模型属性。
示例:
@Controller
public class UserController {// 添加模型属性@ModelAttribute("allUsers")public List<User> populateUsers() {// 从数据库获取所有用户List<User> users = userService.findAll();return users;}// 绑定请求参数到模型对象@PostMapping("/saveUser")public String saveUser(@ModelAttribute("user") User user) {// 保存用户到数据库userService.save(user);return "redirect:/users";}@GetMapping("/users")public String listUsers(Model model) {// 此时模型中已经包含 allUsers 属性return "userList";}
}
在这个例子中,populateUsers 方法被 @ModelAttribute 注解,它会在每个请求处理之前执行,并将所有用户添加到模型中。saveUser 方法使用 @ModelAttribute 注解将请求参数绑定到 User 对象上。listUsers 方法则简单地返回一个视图名,视图模板可以访问 allUsers 模型属性。