在 Spring Boot 开发 RESTful API 时,@PathVariable 和 @RequestParam 是从 URL 中获取参数的两大核心注解,也是控制器方法中最常用的参数绑定注解。 二者的核心分工遵循 RESTful 设计规范:@PathVariable 用于定位资源,@RequestParam 用于筛选 / 过滤资源,清晰的分工能让接口语义更明确、代码更规范。
用于绑定 URL 路径中的动态占位符 到方法参数,唯一作用是定位服务器资源(如用户 ID、订单编号),是 RESTful 风格的标志性注解。 数据来源:URL 路径本体(非 ? 后的参数)。
用于标识唯一资源,不可或缺
默认必填,缺失会直接返回 404 错误
不支持默认值(Spring 4.3+ 可通过配置实现可选)
支持正则表达式限制参数格式
Spring 自动完成类型转换(String → Long/Integer/UUID 等)
占位符与参数名一致:@PathVariable Long id
名称不一致:@PathVariable("userId") Long id
多路径变量:/users/{userId}/orders/{orderId}
@RestController
@RequestMapping("/api/users")
public class UserController {
// 1. 基础用法:根据ID查询用户 GET /api/users/1001
@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
User user = userService.getById(id);
return ResponseEntity.ok(user);
}
// 2. 多路径变量:查询用户的指定订单 GET /api/users/1001/orders/2002
@GetMapping("/{userId}/orders/{orderId}")
public ResponseEntity<Order> getUserOrder(
@PathVariable Long userId,
@PathVariable Long orderId
) {
Order order = orderService.getByUserIdAndOrderId(userId, orderId);
return ResponseEntity.ok(order);
}
// 3. 正则限制:仅允许数字ID(防止非法参数)
@GetMapping("/{id:\\d+}")
public ResponseEntity<User> getUserByRegex(@PathVariable Long id) {
return ResponseEntity.ok(userService.getById(id));
}
}用于绑定 URL 查询字符串(? 后的键值对) 到方法参数,用于对资源进行筛选、分页、排序、搜索,不负责定位资源。 数据来源:?key=value&key2=value2。
用于辅助查询,支持可选参数
可配置 required:是否必填(默认 true)
支持 defaultValue:设置默认值
支持接收数组、集合(多值参数)
缺失必填参数会返回 400 错误
参数名一致:@RequestParam String name
可选参数:@RequestParam(required = false) String name
带默认值:@RequestParam(defaultValue = "1") Integer page
多值参数:@RequestParam List<Long> ids
@RestController
@RequestMapping("/api/users")
public class UserController {
// 1. 基础必填参数:按姓名搜索 GET /api/users/search?name=张三
@GetMapping("/search")
public ResponseEntity<List<User>> searchUser(@RequestParam String name) {
return ResponseEntity.ok(userService.findByName(name));
}
// 2. 可选+默认值:分页查询 GET /api/users/page
@GetMapping("/page")
public ResponseEntity<Page<User>> pageQuery(
// 可选参数,无默认值
@RequestParam(required = false) String keyword,
// 必填,默认值1
@RequestParam(defaultValue = "1") Integer page,
// 必填,默认值10
@RequestParam(defaultValue = "10") Integer size
) {
return ResponseEntity.ok(userService.page(keyword, page, size));
}
// 3. 多值参数:批量查询 GET /api/users/batch?ids=1,2,3
@GetMapping("/batch")
public ResponseEntity<List<User>> batchGet(@RequestParam List<Long> ids) {
return ResponseEntity.ok(userService.listByIds(ids));
}
}实际开发中,资源定位 + 条件筛选 是最常用的组合方式:
示例:查询指定用户的已支付订单(路径变量定位用户,查询参数筛选订单状态)
@RestController
@RequestMapping("/api/users")
public class OrderController {
/**
* 请求地址:GET /api/users/1001/orders?status=PAID&page=1&size=5
* 路径变量:userId=1001
* 查询参数:status=PAID、page=1、size=5
*/
@GetMapping("/{userId}/orders")
public ResponseEntity<Page<Order>> getUserOrders(
@PathVariable Long userId,
@RequestParam String status,
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "5") Integer size
) {
Page<Order> orders = orderService.getUserOrders(userId, status, page, size);
return ResponseEntity.ok(orders);
}
}@PathVariable 原生不支持默认值,但可通过可选占位符实现:
// 匹配 /users 或 /users/1001
@GetMapping({"/users", "/users/{id}"})
public ResponseEntity<List<User>> getUsers(@PathVariable(required = false) Long id) {
if (id == null) return ResponseEntity.ok(userService.listAll());
return ResponseEntity.ok(Collections.singletonList(userService.getById(id)));
}在 Spring Boot 2.0+ 中,参数名与占位符 / 查询参数名一致时,可省略注解:
// 等价 @PathVariable Long id
@GetMapping("/{id}")
public User getUser(Long id) { ... }
// 等价 @RequestParam String name
@GetMapping("/search")
public List<User> search(String name) { ... }Spring 会自动将 URL 中的字符串转换为目标类型(Long/Integer/UUID 等),转换失败抛出 TypeMismatchException,可通过全局异常处理统一返回:
@ExceptionHandler(TypeMismatchException.class)
public ResponseEntity<String> handleTypeError() {
return ResponseEntity.badRequest().body("参数格式错误!");
}@PathVariable/@RequestParam:从 URL 取参,适合简单参数
@RequestBody:从 请求体 取参,适合复杂 JSON 对象
核心分工 @PathVariable = 定位资源(URL 路径),@RequestParam = 筛选资源(URL 查询参数);
使用规则 定位用路径变量、筛选用查询参数,二者配合实现标准 RESTful 接口;
关键特性 路径变量必填无默认值、查询参数可选支持默认值,错误类型分别为 404/400;
开发规范 保留注解提升可读性,严格校验参数,不传递敏感数据,让接口更规范、更安全。