本篇是《Spring Boot 4 学习从入门到大神》专栏第 7 篇。
参数是接口的"入口",也是 Bug 的高发区。本文将系统讲解 Spring Boot 4 中各种参数接收方式、底层原理、复杂类型绑定、参数校验和常见坑位,帮你彻底搞定接口参数。
一、HTTP 请求参数到底在哪?
先建立一张全局认知图:
| 参数位置 | 对应注解 | 示例 |
|---|---|---|
| URL 路径 | @PathVariable |
/users/{id} |
| URL 查询串 | @RequestParam |
/users?id=1 |
| 请求体(JSON) | @RequestBody |
{ "name": "张三" } |
| 请求头 | @RequestHeader |
Authorization: Bearer xxx |
| Cookie | @CookieValue |
JSESSIONID=xxx |
| 表单 | @RequestParam / @ModelAttribute |
username=zhangsan |
📌 Spring Boot 4 的核心能力:自动从请求中"找"参数并绑定到方法参数。
二、@PathVariable:从 URL 路径中取参
1️⃣ 基本用法
@GetMapping("/users/{id}")
public Result<UserVO> getUser(@PathVariable Long id) {
return Result.success(userService.getById(id));
}
URL:
GET /users/1
2️⃣ 指定变量名(推荐)
@GetMapping("/users/{userId}")
public Result<UserVO> getUser(@PathVariable("userId") Long id) {
}
✅ 变量名不一致时必须指定
3️⃣ 多个路径参数
@GetMapping("/companies/{companyId}/users/{userId}")
public Result<UserVO> getUser(
@PathVariable Long companyId,
@PathVariable Long userId) {
}
URL:
GET /companies/1/users/10
4️⃣ 正则表达式约束(高级)
@GetMapping("/users/{id:\\d+}")
public Result<UserVO> getUser(@PathVariable Long id) {
}
✅ 只匹配数字,非法请求直接 404
三、@RequestParam:从查询参数中取参
1️⃣ 基本用法
@GetMapping("/users")
public Result<List<UserVO>> listUsers(
@RequestParam String name,
@RequestParam Integer age) {
}
URL:
GET /users?name=zhangsan&age=18
2️⃣ 参数可选与默认值(非常重要)
@GetMapping("/users")
public Result<List<UserVO>> listUsers(
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer size,
@RequestParam(required = false) String keyword) {
}
✅ required = false:参数可缺省
✅ defaultValue:参数不存在时的默认值
3️⃣ 接收数组 / List
@GetMapping("/users")
public Result<List<UserVO>> listUsers(@RequestParam List<Long> ids) {
}
URL:
GET /users?ids=1,2,3
GET /users?ids=1&ids=2&ids=3
四、@RequestBody:接收请求体(JSON)
1️⃣ 接收单个对象
@PostMapping("/users")
public Result<UserVO> createUser(@RequestBody UserDTO dto) {
return Result.success(userService.create(dto));
}
Body:
{
"username": "zhangsan",
"age": 18,
"email": "zs@test.com"
}
2️⃣ 接收 List / Map
@PostMapping("/users/batch")
public Result<List<UserVO>> batchCreate(@RequestBody List<UserDTO> dtos) {
}
@PostMapping("/users/map")
public Result<?> save(@RequestBody Map<String, Object> map) {
}
3️⃣ JSON 字段与 Java 字段映射
public record UserDTO(
@JsonProperty("user_name") String username,
Integer age
) {}
✅ 前端传 user_name,后端用 username
五、复杂对象绑定(非常实用)
1️⃣ 嵌套对象
public record OrderDTO(
Long id,
UserDTO user,
List<ItemDTO> items
) {}
JSON:
{
"id": 1001,
"user": { "username": "zhangsan" },
"items": [{ "name": "iPhone" }]
}
2️⃣ @RequestParam 绑定到对象(表单提交)
@PostMapping("/users")
public Result<?> createUser(UserDTO dto) {
}
HTML 表单:
<input name="username" value="zhangsan"/>
<input name="age" value="18"/>
📌 没有注解时,Spring 会按参数名从请求中查找
六、其他常用参数注解
1️⃣ @RequestHeader(请求头)
@GetMapping("/users")
public Result<?> getUser(@RequestHeader("Authorization") String token) {
}
2️⃣ @CookieValue(Cookie)
@GetMapping("/users")
public Result<?> getUser(@CookieValue("JSESSIONID") String sessionId) {
}
3️⃣ @MatrixVariable(矩阵参数,冷门但高级)
URL:
/users/id=1;name=zhangsan;age=18
@GetMapping("/users/{id}")
public Result<?> getUser(@MatrixVariable String name) {
}
七、参数校验(JSR‑303,生产级必备)
1️⃣ 引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
2️⃣ DTO 中加校验注解
public record UserDTO(
@NotBlank(message = "用户名不能为空")
String username,
@Min(value = 1, message = "年龄必须大于 0")
Integer age,
@Email(message = "邮箱格式不正确")
String email
) {}
3️⃣ 开启校验
@PostMapping("/users")
public Result<?> createUser(@Valid @RequestBody UserDTO dto) {
}
4️⃣ 统一异常处理(下篇会详细讲)
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public Result<?> handleValidException(MethodArgumentNotValidException e) {
String msg = e.getBindingResult().getFieldError().getDefaultMessage();
return Result.fail(400, msg);
}
}
八、参数绑定的底层原理
Spring Boot 4 内部流程:
-
DispatcherServlet接收请求 -
HandlerMapping找到 Controller 方法 -
HandlerAdapter调用方法 -
**参数解析器(HandlerMethodArgumentResolver)** 负责参数绑定
-
@PathVariable→PathVariableMethodArgumentResolver -
@RequestParam→RequestParamMethodArgumentResolver -
@RequestBody→RequestResponseBodyMethodProcessor
-
-
数据类型转换(Converter)
-
参数校验(Validator)
📌 一句话总结:
不同的注解,背后是不同的参数解析器。
九、常见坑位总结(血泪教训)
❌ 坑1:GET 请求用 @RequestBody
✅ GET 没有请求体
❌ 坑2:@RequestParam 接收 JSON
✅ JSON 必须用 @RequestBody
❌ 坑3:List 参数接收失败
✅ 要么用 @RequestParam List<Long> ids
✅ 要么用 @RequestBody List<Long> ids
❌ 坑4:参数校验不生效
✅ 忘记加 @Valid
✅ 忘记引入 spring-boot-starter-validation
❌ 坑5:前端传 null,后端用基本类型
@RequestParam int age // ❌
@RequestParam Integer age // ✅
十、本篇总结
-
@PathVariable:URL 路径参数
-
@RequestParam:查询参数 / 表单
-
@RequestBody:JSON 请求体
-
参数校验用 JSR‑303 + @Valid
-
不同注解 = 不同参数解析器