前言
RFC3986定義URI的路徑(Path)中可包含name-value片段,擴充了以往僅能通過查詢字串(Query String)設定可選引數的囧境。
假如現在需要設計一個用於“搜尋某部門某些員工可選資訊中的部分資訊”的API,我們分別使用查詢字串和路徑name-value方式來設計對比,看看具體效果:
- 查詢字串方式:
/api/v1/users/optional-info?dept=321&name=joh*&fields=hometown,birth
問題:其中的dept和name理應屬於users路徑,而fields則屬於optional-info路徑,但現在全部都要擠在查詢字串中。 - 路徑name-value方式:
/api/v1/users/depts=321;name=joh*/optional-fields/fields=hometown,birth
可以看出路徑name-value的方式邏輯上更在理些。
@MatrixVariable註解屬性說明
在正式開始前我們先死記硬背一下註解的屬性吧。
value
和屬性pathVar
的別名;pathVar
用於指定name-value引數所在的路徑片段名稱name
用於指定name-value引數的引數名required
是否為必填值,預設為falsedefaultValue
設定預設值
其中pathVar
和name
到底是什麼呢?請繼續看後面的示例吧,準能秒懂!
啟用@MatrixVariable
雖然從Spring 3.2就已經支援@MatrixVariable
特性,但直至現在其依然為預設禁用的狀態。我們需要手工配置開啟才能使用。
@Configuration
public class SpringBootConfig implements WebMvcConfigurer {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
UrlPathHelper urlPathHelper = new UrlPathHelper();
urlPathHelper.setRemoveSemicolonContent(false);
configurer.setUrlPathHelper(urlPathHelper);
}
}
引數僅有一個值的玩法
注意:多個name-value間以分號分隔,如name=joh*;dept=321
。
/*
1. 獲取單個路徑片段中的引數
請求URI為 /Demo2/66;color=red;year=2020
*/
@RequestMapping(path="/Demo1/{id}", method=RequestMethod.GET)
public String test1(@PathVariable String id, @MatrixVariable String color, @MatrixVariable String year){}
/*
2. 獲取單個路徑片段中的引數
請求URI為 /Demo2/color=red;year=2020
*/
@RequestMapping(path="/Demo1/{id}", method=RequestMethod.GET)
public String test2(@MatrixVariable String color, @MatrixVariable String year){}
/*
3. 獲取不同路徑片段中的引數
請求URI為 /Demo2/66;color=red;year=2020/pets/77;color=blue;year=2019
*/
@RequestMapping(path="/Demo2/{id1}/pets/{id2}", method=RequestMethod.GET)
public String test3(@PathVariable String id1, @PathVariable String id2,
@MatrixVariable(name="color", pathVar="id1") String color1, @MatrixVariable(name="year", pathVar="id1") String year1,
@MatrixVariable(name="color", pathVar="id2") String color2, @MatrixVariable(name="year", pathVar="id2") String year2){}
/*
4. 獲取不同路徑片段中的引數
請求URI為 /Demo2/color=red;year=2020/pets/77;color=blue;year=2019
*/
@RequestMapping(path="/Demo2/{id1}/pets/{id2}", method=RequestMethod.GET)
public String test4(@PathVariable String id2,
@MatrixVariable(name="color", pathVar="id1") String color1, @MatrixVariable(name="year", pathVar="id1") String year1,
@MatrixVariable(name="color", pathVar="id2") String color2, @MatrixVariable(name="year", pathVar="id2") String year2){}
/*
5. 通過Map獲取所有或指定路徑下的所有引數
*/
@RequestMapping(path="/Demo3/{id1}/pets/{id2}", method=RequestMethod.GET)
public String test5(@MatrixVariable Map<String, Object> all, @MatrixVariable(pathVar="id1") Map<String, Object> mapId1) {}
引數有多個值的玩法
若引數值不是單個,那麼可以通過兩種方式傳遞:
- 值之間通過逗號分隔,如
dept=321,123
- 重名name-value對,如
dept=321;dept=123
/*
請求為/Demo1/color=123,321
那麼color值為123,321
*/
@RequestMapping(path="/Demo1/{id}", method=RequestMethod.GET)
public String test1(@MatrixVariable Integer[] color){}
/*
請求為/Demo1/color=123;color=321
那麼color值為123,321
*/
@RequestMapping(path="/Demo1/{id}", method=RequestMethod.GET)
public String test1(@MatrixVariable Integer[] color){}
那些要注意的坑
在引數多值的情況下還有如下3個坑,請各位多加註意:
String
引數型別可以接受通過逗號和通過重名name-value傳遞的所有值,而其它型別只能獲取第一個值。
/*
請求為/Demo1/color=123,321
那麼color值為123,321
*/
@RequestMapping(path="/Demo1/{id}", method=RequestMethod.GET)
public String test1(@MatrixVariable String color){}
/*
請求為/Demo1/color=123;color=321
那麼color值為123,321
*/
@RequestMapping(path="/Demo1/{id}", method=RequestMethod.GET)
public String test1(@MatrixVariable String color){}
/*
請求為/Demo1/color=123;color=321
那麼color值為123
*/
@RequestMapping(path="/Demo1/{id}", method=RequestMethod.GET)
public String test1(@MatrixVariable Integer color){}
Map<String, Object[]>
只能獲取引數中的第一個值而已。
/*
請求為/Demo1/color=123,321
那麼color值為123
*/
@RequestMapping(path="/Demo1/{id}", method=RequestMethod.GET)
public String test1(@MatrixVariable Map<String, Integer[]> color){}
- 不同路徑片段中出現名稱相同的引數,那麼必須通過pathVar標識所有相同引數所屬路徑,否則URI匹配失敗。
// 以下handler僅標識第二個引數的pathVar,而沒有標識第一個,那麼也是會匹配失敗的。
@RequestMapping(path="/Demo2/{id1}/pets/{id2}", method=RequestMethod.GET)
public String test2(@MatrixVariable String color, @MatrixVariable(name="color", pathVar="id2") String color2){}
總結
今天就寫到這裡吧,後續會有更多Spring Boot的分享,請大家多關注我哦!
轉載請註明來自: https://www.cnblogs.com/fsjohnhuang/p/14284988.html —— 肥仔John