参数绑定:@RequestParam/@PathVariable/@RequestHeader/@CookieValue
接口方法里写的形参不是凭空来的:Spring 用一组参数解析器(HandlerMethodArgumentResolver)把 URL、请求头、Cookie、请求体里的数据「绑」进方法参数。这一章讲最常用的四个绑定注解。
@RequestParam:绑定查询参数 / 表单字段
默认按参数名匹配,required 默认为 true——缺了就直接抛异常返回 400。建议显式写 name,避免依赖 -parameters 编译开关:
@RestController
public class SearchController {
// GET /api/search?keyword=spring&page=2
@GetMapping("/api/search")
public String search(@RequestParam("keyword") String keyword,
@RequestParam(value = "page", defaultValue = "1") int page) {
return "keyword=" + keyword + ", page=" + page;
}
}
// 输出:keyword=spring, page=2
要点速查:
- required = false:参数可缺省,缺失时得到 null(基本类型请配 defaultValue,否则空指针风险)。
- defaultValue:缺参时兜底,设置了它等价于 required = false。
- 支持 Java 8+ 的 Optional<T> 表达可缺省。
- 多值:
@RequestParam("tag") List<String> tag可收 ?tag=a&tag=b;数组同理。 - Map 收全部:
@RequestParam Map<String, String> params收集所有查询参数。
@PathVariable:绑定路径变量
配合 @RequestMapping 里的 {xxx} 占位符使用:
@GetMapping("/api/users/{id}/orders/{orderId}")
public String order(@PathVariable("id") Long userId,
@PathVariable Long orderId) { // 不写名字时按形参名匹配 {orderId}
return "user=" + userId + ", order=" + orderId;
}
- 路径变量按需做类型转换:{id} 是字符串,参数声明 Long 就会自动转。
- Spring 6 默认采用基于 PathPattern 的匹配策略,花括号语法与通配细节以官方文档为准。
- 与 @RequestParam 最直观的区别:一个来自路径段,一个来自 ?key=value 或表单体。
@RequestHeader:绑定请求头
@GetMapping("/api/agent")
public String agent(@RequestHeader(value = "User-Agent", defaultValue = "unknown") String ua,
@RequestHeader(value = "Accept-Language", required = false) String lang) {
return "ua=" + ua + ", lang=" + lang;
}
@CookieValue:绑定 Cookie
@GetMapping("/api/cart")
public String cart(@CookieValue(value = "JSESSIONID", required = false) String sessionId) {
return "cookie=" + sessionId;
}
四个注解共性速查表
| 注解 | 数据来源 | 典型写法 | 缺省控制 |
|---|---|---|---|
| @RequestParam | 查询串 / 表单字段 | ?id=1 | required / defaultValue |
| @PathVariable | URL 路径段 | /users/{id} | 映射里必须有该变量 |
| @RequestHeader | 请求头 | User-Agent | required / defaultValue |
| @CookieValue | Cookie | JSESSIONID | required / defaultValue |
常见错误提示
- 缺必填参数:MissingServletRequestParameterException(400)。
- 类型转不过去:MethodArgumentTypeMismatchException(400),比如给 int 传了 abc。
- 名字对不上又没开 -parameters:形参名推断失败会 400;最稳妥永远是写全 name。
绑定注解本质是「把 HTTP 世界里散落的字符串取出来并做类型转换」。搞清楚每个注解的数据来源和缺省规则,接口签名就能写得很干净,异常也一眼能定位。