@PathVariable 和 @RequestParam 这两个非常重要的 Spring MVC 注解。
这两个注解都是用于从 HTTP 请求中获取参数 ,并将其绑定到控制器方法的参数上,但它们获取参数的位置 和方式截然不同。
1. @PathVariable("id") Long id
@PathVariable 用于从 URL 的路径中获取参数。
工作原理
当你在 @PutMapping 注解中定义了一个 URL 模板,如 /region-service/{id},其中 {id} 就是一个路径变量。它是 URL 的一部分。
当一个请求发送到 /region-service/100 时:
- Spring MVC 会匹配这个 URL 到
@PutMapping("/region-service/{id}")。 - 它会识别出 URL 中的
100是{id}变量的值。 @PathVariable("id")注解会告诉 Spring MVC:"请把 URL 路径中名为id的那部分的值取出来,转换为Long类型,并赋给我这个也叫id的方法参数。"
代码中的具体场景
在你的代码中:
@PutMapping("/{id}")定义了一个 RESTful 风格的 URL,例如http://your-domain.com/api/services/123。@PathVariable("id") Long id会从这个 URL (/123) 中提取出123这个值,将其转换为Long类型,并传递给update方法的id参数。这个id通常用来唯一标识你要操作的资源(例如,ID 为 123 的服务)。
核心特点
- 位置:参数位于 URL 路径中。
- URL 模板 :通过
{变量名}在@RequestMapping(或其变体) 中定义。 - 必需性 :默认情况下是必需的。如果 URL 中缺少这个路径变量,请求会失败(返回 404 Not Found)。如果想让它非必需,可以设置
@PathVariable(required = false)。 - 常见场景:用于 RESTful API 中,标识资源的唯一ID,如查询、更新、删除某个特定资源。
2. @RequestParam("price") BigDecimal price
@RequestParam 用于从 HTTP 请求的查询参数(Query String)中获取参数。
工作原理
查询参数是 URL 中 ? 后面的部分,例如 http://your-domain.com/api/services/123?price=99.99。这里的 price=99.99 就是一个查询参数。
当一个请求发送到上述 URL 时:
@RequestParam("price")注解会告诉 Spring MVC:"请从请求的查询参数中找到名为price的参数。"- 它会获取其值
"99.99"。 - 然后 Spring MVC 会尝试将这个字符串值转换为
BigDecimal类型,并赋给方法的price参数。
代码中的具体场景
在你的代码中:
@RequestParam("price") BigDecimal price会从请求的 URL 查询参数中获取price的值。- 对于一个完整的请求 URL
http://.../123?price=158.00,price参数的值"158.00"会被提取出来,并转换为BigDecimal类型,传递给update方法。这个price就是你想要更新的新价格。
核心特点
- 位置 :参数位于 URL 的查询字符串中(
?之后)。 - 键值对 :格式为
?key1=value1&key2=value2。 - 必需性 :默认情况下是必需的。如果请求中缺少这个参数,Spring MVC 会抛出
MissingServletRequestParameterException异常(通常导致 400 Bad Request 错误)。你可以通过设置@RequestParam(required = false)来使其成为可选参数。 - 默认值 :可以通过
@RequestParam(defaultValue = "0")为参数提供一个默认值。 - 常见场景:用于接收用户通过表单提交、或在 URL 中附加的过滤条件、分页信息、排序方式等非资源标识类的参数。
总结与对比
| 特性 | @PathVariable |
@RequestParam |
|---|---|---|
| 参数来源 | URL 的路径中 | URL 的查询字符串 中 (? 之后) |
| URL 示例 | /services/**123** |
/services?**price=99.99** |
| 用途 | 通常用于标识一个具体的资源 (如 ID) | 通常用于过滤、排序、分页或传递操作的具体数据 |
| 必需性 | 默认必需 | 默认必需 |
| 获取方式 | request.getPathInfo() (概念上) |
request.getParameter("price") |
在你的代码中的协同作用
你的 update 方法完美地展示了它们的协同工作:
@PathVariable("id")定位到要修改的具体服务(例如,ID 为 123 的服务)。@RequestParam("price")传递要修改的新价格(例如,99.99)。
这个设计非常符合 RESTful API 的风格,清晰地分离了"操作的资源"和"操作的内容"。