前言
将请求参数绑定到模型对象上,或者在请求处理之前添加模型属性
可以在方法参数、方法或者类上使用
一般适用这几种场景:
- 表单处理:通过
@ModelAttribute
将表单数据绑定到模型对象上 - 预处理逻辑:在请求处理之前执行一些初始化操作,如设置常见模型属性
- RESTful API:结合
@RequestBody
处理 JSON 数据
对于Java的相关知识推荐阅读:java框架 零基础从入门到精通的学习路线 附开源项目面经等(超全)
1. 注解用法
1.1 方法参数
将表单参数(name 和 email)绑定到 User 对象上,并将这个对象作为模型属性传递给视图
后端结合User,对应这个User属性要写全,才能获取到对应属性
@Controller
public class UserController {
@RequestMapping(value = "/user", method = RequestMethod.POST)
public String addUser(@ModelAttribute User user, Model model) {
// 处理业务逻辑
model.addAttribute("user", user);
return "userDetails";
}
}
前端对应捕捉相关的表单值
<form action="/user" method="post">
<input type="text" name="name" />
<input type="text" name="email" />
<button type="submit">Submit</button>
</form>
1.2 方法
控制器方法上使用 @ModelAttribute
注解,可以在每个请求处理方法调用之前执行一些预处理操作,如初始化模型数据
对应的后端示例如下:
@Controller
public class UserController {
@ModelAttribute
public void addAttributes(Model model) {
model.addAttribute("message", "Welcome to the user page!");
}
@RequestMapping(value = "/user", method = RequestMethod.GET)
public String getUserForm(Model model) {
// 模型中已经包含了 "message" 属性
return "userForm";
}
}
前端视图如下:
<!-- userForm.jsp -->
<html>
<body>
<h1>${message}</h1>
<form action="/user" method="post">
<input type="text" name="name" />
<input type="text" name="email" />
<button type="submit">Submit</button>
</form>
</body>
</html>
对应每次请求都会在控制器方法调用之前添加一个名为 "message"
的模型属性
1.3 类
在类上使用 @ModelAttribute
注解,可以为所有该类的请求处理方法添加共同的模型属性
对应后端写法如下:
@Controller
@SessionAttributes("user")
public class UserController {
@ModelAttribute("user")
public User createUser() {
return new User();
}
@RequestMapping(value = "/user", method = RequestMethod.GET)
public String getUserForm(@ModelAttribute("user") User user) {
return "userForm";
}
@RequestMapping(value = "/user", method = RequestMethod.POST)
public String submitUser(@ModelAttribute("user") User user) {
// 处理业务逻辑
return "userDetails";
}
}
2. 注解场景
与上面的第一章有些重复,不过容易理解
2.1 表单参数
表单参数:处理来自前端 HTML 表单的数据,将表单字段绑定到 Java 对象上
(其Demo对应此章的1.1)
也可通过编辑用户信息,绑定到相关的模型对象
@Controller
public class UserController {
@RequestMapping(value = "/user/edit", method = RequestMethod.GET)
public String editUser(@ModelAttribute User user, @RequestParam("userId") Long userId, Model model) {
// 通过 userId 获取用户信息并填充到 user 对象
user = userService.findById(userId);
model.addAttribute("user", user);
return "editUserForm";
}
}
2.2 AJAX请求
配合前端进行交互,此处写一个示例的Demo
使用 JavaScript(例如 jQuery 或者原生的 XMLHttpRequest)发送异步请求,后端通过 @RequestBody
结合 @ModelAttribute
解析 JSON 数据
$.ajax({
url: '/user',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({ name: 'John', email: 'john@example.com' }),
success: function(response) {
console.log(response);
}
});
对应后端如下:
@Controller
public class UserController {
@RequestMapping(value = "/user", method = RequestMethod.POST)
@ResponseBody
public User addUser(@RequestBody @ModelAttribute User user) {
// 处理业务逻辑
return user;
}
}
2.3 文件上传
前端使用 <form>
标签并设置 enctype="multipart/form-data"
,后端通过 @ModelAttribute
绑定文件数据
前端:
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="file" />
<button type="submit">Upload</button>
</form>
后端:
@Controller
public class FileUploadController {
@RequestMapping(value = "/upload", method = RequestMethod.POST)
public String handleFileUpload(@RequestParam("file") MultipartFile file) {
// 处理文件上传逻辑
return "fileUploadSuccess";
}
}
3. 实战
通过实战前端交互加深印象
此处使用Vue3 + Java
对应的函数调用如下:
options中添加了file的对应属性,但是后续需要将id传输给后端
对应的JS如下:
// 上传文件
export const updateFile = (data: any) => {
const formData = new FormData();
formData.append('file', data.file);
formData.append('appointmentId', data.id.toString());
return request.upload({
url: '/dangerous/appointment-commission/appointment-file/upload',
data: formData
});
}
其后端的写法如下:
@PostMapping("/appointment-file/upload")
@Operation(summary = "上传文件", description = "模式一:后端上传文件")
public CommonResult<String> uploadFile(@ModelAttribute FileUploadReqVO uploadReqVO,@RequestParam("appointmentId") Long appointmentId) throws Exception {
MultipartFile file = uploadReqVO.getFile();
String path = uploadReqVO.getPath();
return success(appointmentCommissionService.createFile(file.getOriginalFilename(), path, IoUtil.readBytes(file.getInputStream()),appointmentId));
}
4. 总结
@RequestBody
:数据来自请求体,通常是 JSON 格式
@Controller
public class UserController {
@RequestMapping(value = "/api/user", method = RequestMethod.POST)
@ResponseBody
public User addUser(@RequestBody User user) {
// 处理 JSON 请求体
return user;
}
}
@ModelAttribute
:数据来自 URL 查询参数、表单参数,或其他请求参数
@Controller
public class UserController {
@RequestMapping(value = "/form/user", method = RequestMethod.POST)
public String addUser(@ModelAttribute User user) {
// 处理表单参数
return "userDetails";
}
}
其他注解详情如下: