介绍
URI 规范 RFC 3986 中 URL 的定义,路径片段中可以包含键值对。规范中没有对应的术语。
随之在 Spring MVC 3.2 中出现了 @MatrixVariable 注解,该注解的出现使得开发人员能够将请求中的矩阵变量(MatrixVariable)绑定到处理器的方法参数中。
springBoot配置(2.3)
在SpringBoot2.3中默认是关闭矩阵变量的功能的(其他版本没有看)。
源码在WebMvcAutoConfiguration的WebMvcAutoConfigurationAdapter内部类中:
有实现WebMvcConfigurer接口,默认实现了configurePathMatch方法,该方法中向PathMatchConfigurer中添加了UrlPathHelper
UrlPathHelper:removeSemicolonContent该属性控制是否移除分号,默认为true(移除分号),矩阵变量功能不开启
所以我们只需要重新实现WebMvcConfigurer的该方法即可:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
UrlPathHelper urlPathHelper = new UrlPathHelper();
//不移除url中分号后面中的内容
urlPathHelper.setRemoveSemicolonContent(false);
configurer.setUrlPathHelper(urlPathHelper);
}
}
测试
注意矩阵变量必须写在路径变量中
@RequestMapping("/test/{id}/{name}")
public Map test(@PathVariable Integer id,
@MatrixVariable String a,
@MatrixVariable List<Integer> b,
@PathVariable String name,
@MatrixVariable char c,
@MatrixVariable Boolean flag){
Map<String, Object> map = new HashMap<>();
map.put("id",id);
map.put("a", a);
map.put("b", b);
map.put("name", name);
map.put("c", c);
map.put("flag", flag);
return map;
}
发送请求
http://localhost:8080/test/1;a=wj;b=1,2,3/wen;c=q;flag=true
返回结果:
注意:MatrixVariable注解中有一个required属性默认为true,所以默认情况下,url中必须携带矩阵变量,否则就会报错。当然我们也可以将该属性设置为false。
如果:有相同的矩阵变量参数
http://localhost:8080/test2/wen;age=20/jie;age=30
使用如下代码接收就会报错:
@RequestMapping("/test2/{boss}/{emp}")
public Map test2(@PathVariable String boss,@PathVariable String emp,
@MatrixVariable(name = "age")Integer bossAge,
@MatrixVariable(name = "age") Integer empAge){
Map<String, Object> map = new HashMap<>();
map.put("boss", boss);
map.put("emp", emp);
map.put("bossAge", bossAge);
map.put("empAge", empAge);
return map;
}
报错信息:说我们不只有一个age参数去匹配,我们可以用pathVar属性去区分
@RequestMapping("/test2/{boss}/{emp}")
public Map test2(@PathVariable String boss,@PathVariable String emp,
@MatrixVariable(name = "age", pathVar = "boss")Integer bossAge,
@MatrixVariable(name = "age", pathVar = "emp") Integer empAge){
Map<String, Object> map = new HashMap<>();
map.put("boss", boss);
map.put("emp", emp);
map.put("bossAge", bossAge);
map.put("empAge", empAge);
return map;
}