📚 目录

  1. 参数绑定概述与机制
  2. 单个参数绑定(URL、表单)
  3. 多参数绑定(URL、表单)
  4. Java Bean(POJO)对象绑定
  5. 集合(List/Map/数组)绑定
  6. JSON 请求体绑定(@RequestBody)
  7. 日期/格式转换绑定(@InitBinder)
  8. 文件上传绑定(MultipartFile)
  9. 参数绑定常见注解总结
  10. 实战建议与注意事项

1. 参数绑定概述与机制

Spring MVC 使用 DispatcherServlet 将 HTTP 请求参数自动映射到 Controller 方法的形参。
底层使用 HandlerMethodArgumentResolver 接口,结合类型推断与注解驱动来完成绑定。


2. 单个参数绑定(默认支持)

绑定路径参数 / 查询参数

@GetMapping("/user")
public String getUser(@RequestParam String name, @RequestParam int age) {
    // ?name=Tom&age=20
    ...
}

默认值与可选参数

@GetMapping("/user")
public String getUser(@RequestParam(defaultValue = "guest") String name,
                      @RequestParam(required = false) Integer age) {
    ...
}

3. 多参数绑定(URL 或表单提交)

<form method="post" action="/login">
  <input name="username" />
  <input name="password" />
</form>
@PostMapping("/login")
public String login(@RequestParam String username, @RequestParam String password) {
    ...
}

4. Java Bean(POJO)对象绑定

<input name="user.name" />
<input name="user.age" />
public class User {
    private String name;
    private Integer age;
    // getters and setters
}
@PostMapping("/save")
public String saveUser(@ModelAttribute User user) {
    ...
}

支持嵌套对象:

<input name="user.address.street" />

5. 集合参数绑定

List/数组绑定

<input name="hobbies" value="reading" />
<input name="hobbies" value="coding" />
@PostMapping("/hobby")
public String submit(@RequestParam List<String> hobbies) {
    ...
}

POJO 集合绑定(List)

<input name="users[0].name" />
<input name="users[1].name" />
@PostMapping("/users")
public String saveUsers(UserListWrapper wrapper) {
    // wrapper.getUsers()
}
public class UserListWrapper {
    private List<User> users;
    // getter/setter
}

6. JSON 请求体绑定(@RequestBody)

适用于前后端分离、Axios/AJAX/Fetch JSON 提交

{
  "name": "Tom",
  "age": 22
}
@PostMapping("/api/user")
@ResponseBody
public String saveUser(@RequestBody User user) {
    ...
}

✔️ 支持集合:

[
  {"name":"Tom"},
  {"name":"Lucy"}
]
@PostMapping("/api/users")
@ResponseBody
public String saveUsers(@RequestBody List<User> users) {
    ...
}

7. 日期格式转换与 @InitBinder

不同格式自动转换失败示例:

@PostMapping("/date")
public String save(@RequestParam Date birthday) {
    // 2023-01-01 OK,但 01/01/2023 可能报错
}

正确做法(使用格式化器):

@InitBinder
public void initBinder(WebDataBinder binder) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    sdf.setLenient(false);
    binder.registerCustomEditor(Date.class, new CustomDateEditor(sdf, false));
}

8. 文件上传绑定(MultipartFile)

HTML 表单:

<form action="/upload" method="post" enctype="multipart/form-data">
  <input type="file" name="file" />
  <button type="submit">上传</button>
</form>

Controller 方法:

@PostMapping("/upload")
public String upload(@RequestParam("file") MultipartFile file) throws IOException {
    String name = file.getOriginalFilename();
    byte[] content = file.getBytes();
    ...
}

✔️ 多文件:

public String upload(@RequestParam("files") MultipartFile[] files)

✔️ 设置最大文件大小:

spring:
  servlet:
    multipart:
      max-file-size: 10MB
      max-request-size: 20MB

9. 常用参数绑定注解总结表

注解用途
@RequestParam获取 URL/query/form 的单个参数
@PathVariable获取路径参数,如 /user/{id}
@RequestBody获取 JSON 请求体
@ModelAttribute绑定表单数据至对象(支持嵌套)
@RequestHeader获取请求头参数,如 token、UA 等
@CookieValue获取指定 Cookie 值
MultipartFile获取上传的文件

🔚 10. 实战建议与注意事项

建议原因与说明
避免使用 @RequestParam 处理 JSON 请求体会导致 415 错误,应改用 @RequestBody
表单提交对象优先使用 @ModelAttribute支持嵌套、封装性强
对于日期字段统一使用 @InitBinder 配置格式化避免前端格式错导致绑定失败
上传文件使用 MultipartFile 不要写 byte[]更安全、支持更多操作
使用 BindingResult 校验绑定后的错误信息避免程序崩溃、提升用户体验

🔗 参考资料

  • Spring MVC 官方文档
  • 《Spring 实战》第5版(Spring In Action)
  • GitHub 示例项目:spring-mvc-param-binding-demo