別不信@PathVariable你真不會(huì)用
1. 簡介
@PathVariable是Spring MVC中的一個(gè)非常重要的注解,作用在于將URL中的模板變量(即路徑變量)綁定到控制器方法的參數(shù)上。這一功能特別適用于處理RESTful風(fēng)格的請(qǐng)求,使得開發(fā)者能夠直接從URL中提取參數(shù)值,并將其傳遞給方法進(jìn)行處理。通過使用@PathVariable注解,可以設(shè)計(jì)出更加靈活和動(dòng)態(tài)的URL映射,同時(shí)簡化參數(shù)傳遞的過程,提高代碼的可讀性和可維護(hù)性。
接下來,我將深入解析@PathVariable注解的多種使用方式,展示其在實(shí)際開發(fā)中的靈活性和強(qiáng)大功能??纯茨愣颊莆樟藥追N應(yīng)用技巧。
2. 實(shí)戰(zhàn)案例
2.1 基本使用
為使映射正確工作,捕獲 URI 變量 {id} 的名稱必須與 @PathVariable 成員參數(shù) String id 相同。
@GetMapping("/{id}")
public Object id(@PathVariable Long id) {
return id ;
}
圖片
如果將參數(shù)名修改如下:
@PathVariable Long key
這將導(dǎo)致錯(cuò)誤
MissingPathVariableException: Required URI template
variable 'key' for method parameter type Long is not present]
所以,在這種情況下你參數(shù)的名稱要與模板中的一樣。
2.2 不同參數(shù)名
我們可以通過將參數(shù)傳遞給 @PathVariable 注解,顯式訪問捕獲 URI 變量。
@GetMapping("/{id}")
public Object id(@PathVariable("id") Long key) {
return key ;
}
通過指明路徑參數(shù)名,這樣就不會(huì)報(bào)錯(cuò)了。
2.3 類級(jí)別的路徑變量
下面的示例展示了如何使用 @PathVariable 在類和方法級(jí)別訪問URI 變量。
@RestController
@RequestMapping("/pv/{type}")
public class PathVariableController {
@GetMapping("/{id}")
public Object id(@PathVariable Integer type, @PathVariable("id") Long key) {
return type + "@" +key ;
}
}
這里的路徑變量type與參數(shù)名一致所以不用指定名稱。
2.4 多個(gè)URI變量
你也可以定義多個(gè) @PathVariable 注解來訪問捕獲的 URI 變量。
@GetMapping("/{cate}/{id}")
public Object category(@PathVariable String cate, @PathVariable Long id) {
return cate + "@" + id ;
}
只要你想,只要不超過GET請(qǐng)求大小限制,你可以設(shè)置N多的路徑參數(shù)。
2.5 Map接收路徑變量
@PathVariable注解還支持Map類型,如下示例:
@GetMapping("/api/{tag}/query/{name}")
public String getByTagAndName(@PathVariable Map<String, String> paths) {
String tag = paths.get("tag");
String name = paths.get("name");
return tag + "@" + name ;
}
圖片
2.6 正則路徑變量
@GetMapping("/vk/api/{name:[a-z]+}")
public String getJarFile(@PathVariable String name) {
return name ;
}
該路徑將只會(huì)匹配最后的name為a~z組合的字符。
2.7 可選的路徑變量
默認(rèn)情況下@PathVariable路徑變量是必須,否則服務(wù)端將MethodArgumentTypeMismatchException異常。我們除了可以通過設(shè)置PathVariable注解的required屬性為false外,還可以通過Optional類型接收值,如下示例:
@GetMapping({"/users/{id}", "/users/"})
public Object byId(@PathVariable Optional<Long> id) {
return id.orElseGet(() -> -1L) ;
}
匹配兩個(gè)路徑,沒有id則返回-1。
2.8 路徑后綴
關(guān)于路徑后綴匹配,當(dāng)你在應(yīng)用中開啟了后綴匹配時(shí),如果路徑參數(shù)中有后綴那么得到的結(jié)果將不會(huì)是你期望的,如下示例:
@GetMapping("/ext/api/{file}")
public Object fileExt(@PathVariable String file) {
return new R(file) ;
}
請(qǐng)求結(jié)果:
圖片
最終得到的值沒有后綴,對(duì)于這種情況,你需要使用正則的方式處理,如下:
@GetMapping("/ext/api/{file:.+}")
public Object fileExt(@PathVariable String file)
通過這種方式后,你將會(huì)得到完整的后綴信息。
注:從Spring的某個(gè)版本開始這個(gè)后綴已經(jīng)被聲明過時(shí)不建議再使用了,配置文件中對(duì)應(yīng)的參數(shù)都刪除了,所以目前你只能通過自定義WebMvcConfigurer方式開啟后綴匹配。
2.9 在非Controller中取得路徑變量
通常請(qǐng)求的路徑變量是在Controller層被捕獲并處理的。如果你希望在Service層或其他非Controller組件中獲取這些路徑變量,而不是通過參數(shù)傳遞的方式,你則可以通過如下的方式。
private HttpServletRequest request ;
public void uriVar() {
Map<String, String> vars = (Map<String, String>)request
.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE) ;
}
這將獲取所有的路徑變量數(shù)據(jù)。