@PathVariable和@RequestParam

一、注解出处与基础概念

1. @PathVariable

所属包org.bind.annotation
首次引入:Spring 2.5(随 Spring MVC 早期版本)
核心作用:从 URI 路径模板 中提取动态参数,用于标识唯一资源。

2. @RequestParam

所属包org.springframework.web.bind.annotation
首次引入:Spring 2.5
核心作用:从 HTTP 请求的查询参数(Query Parameters) 中提取值,常用于过滤、分页等操作。


二、核心区别对比

特性 @PathVariable @RequestParam
参数来源 URI 路径中的动态片段 URL 查询参数(?key=value
是否必需 默认必填(若 URI 模板声明则必须匹配) 默认非必填(可通过 required=false 修改)
适用场景 标识资源(如 /users/{id} 过滤、排序、分页(如 ?page=2&size=10
RESTful 语义 表示资源唯一性 表示附加操作条件
示例 URL GET /api/users/123 GET /api/users?role=admin

三、用法详解与代码示例

1. @PathVariable 用法

语法@PathVariable(name="param", required=true)
应用场景:获取 URI 中的动态变量,通常用于 资源定位

示例代码:
@GetMapping("/users/{userId}/orders/{orderId}")
public ResponseEntity<Order> getOrder(
    @PathVariable Long userId, 
    @PathVariable("orderId") String orderId) { // 显式指定参数名
    Order order = orderService.findOrder(userId, orderId);
    return ResponseEntity.ok(order);
}

匹配的 URL/users/456/orders/ORDER-789
输出结果:获取用户 456 的订单 ORDER-789 的详细信息。

注意事项:

• 若方法参数名与 URI 变量名一致(如 userId),可省略 name 属性。
• 若 URI 模板中未定义变量,使用 @PathVariable 会抛出 MissingPathVariableException


2. @RequestParam 用法

语法@RequestParam(name="param", required=true, defaultValue="")
应用场景:获取 URL 查询参数,常用于 过滤、分页、排序

示例代码:
@GetMapping("/users")
public ResponseEntity<List<User>> searchUsers(
    @RequestParam(required = false) String name,
    @RequestParam(defaultValue = "0") int page,
    @RequestParam(defaultValue = "10") int size) {
    List<User> users = userService.search(name, page, size);
    return ResponseEntity.ok(users);
}

匹配的 URL/users?name=Alice&page=2&size=20
• 返回第 2 页、每页 20 条,且名字包含 “Alice” 的用户列表。

注意事项:

• 若请求未提供必填参数(required=true),会抛出 MissingServletRequestParameterException
• 可通过 defaultValue 设置默认值(即使 required=false 也建议设置,避免空指针)。


四、混合使用场景

1. 同时使用路径变量和查询参数
@GetMapping("/products/{category}")
public ResponseEntity<List<Product>> getProductsByCategory(
    @PathVariable String category,
    @RequestParam(required = false) String brand,
    @RequestParam(defaultValue = "price,asc")) {
    List<Product> products = productService.filter(category, brand, sort);
    return ResponseEntity.ok(products);
}

匹配的 URL/products/electronics?brand=Samsung&sort=name,desc
输出结果:返回 “electronics” 类别下品牌为 Samsung 并按名称降序排列的商品列表。

五、常见错误与解决方法

1. 路径变量与参数名不匹配

错误代码

@GetMapping("/books/{id}")
public Book getBook(@PathVariable("bookId") Long id) { ... }

报错信息Missing URI template variable 'bookId'
修复方法:确保 @PathVariablename 与 URI 模板变量名一致:

@PathVariable("id") Long bookId
2. 查询参数未传递导致空值

错误代码

@RequestParam String keyword

报错信息Required request parameter 'keyword' is not present
修复方法:设置 required=false 或提供默认值:

@RequestParam(required = false, defaultValue = "") String keyword

六、总结

@PathVariable
用于 资源定位,强调 URI 的层次结构和资源唯一性(如 /users/123)。
设计建议:将唯一标识符(ID、编码等)放在路径中。

@RequestParam
用于 附加操作条件,适合非核心的过滤、分页等场景(如 ?page=2)。
设计建议:避免滥用查询参数传递资源标识,保持 URI 简洁。

两者结合使用可构建清晰、语义化的 RESTful API,例如:

GET /api/v1/products/phones?minPrice=500&maxPrice=1000&brand=Apple

/products/phones:通过路径变量指定资源类别。
minPricemaxPricebrand:通过查询参数实现条件过滤。

你可能感兴趣的:(spring)