写在前面:
根据RFC3986的规范,矩阵变量应当绑定在路径变量中;
若有多个矩阵变量,应当使用英文分号
;
分隔("/search/stu;name=sumu;age=22");若一个矩阵变量有多个值,应当使用英文逗号
,
分隔,或者命名多个重复的key中间使用英文分号;
分隔(如"/search/cars;brand=Audi,Benz,BMW" 或者 "/search/cars;brand=Audi;brand=Benz;brand=BMW")。
一、矩阵变量功能默认不生效原因
1、编写Controller的业务代码
@RestController
public class ParamTestController {
/**
* 语法:/search/cars;low=30;brand=Audi,Benz,BMW
*/
@GetMapping("/search/{path}")
public Map searchCars(@MatrixVariable("low") Integer low,
@MatrixVariable("brand") List<String> brand,
@PathVariable("path") String path) {
Map<String, Object> map = new HashMap<>();
map.put("low", low);
map.put("brand", brand);
map.put("path",path);
return map;
}
}
2、浏览器发送 http://localhost:8080/search/cars;low=30;brand=Audi,Benz,BMW
请求,会发现报一个400错误
3、错误原因分析:
- 由源码可以看到WebMvc自动配置类
WebMvcAutoConfiguration
中的WebMvc自动配置适配器WebMvcAutoConfigurationAdapter
是实现了WebMvcConfigurer
接口并重写了configurePathMatch()
方法 - 由于配置路径匹配方法
configurePathMatch()
需要 Url路径帮助程序UrlPathHelper
来对路径进行解析 - 而
UrlPathHelper
类中的removeSemicolonContent
变量默认值为true
(即:默认删除分号内容) - 因为WebMvc默认删除分号内容,而矩阵变量要绑定在路径变量中并且使用英文分号
;
分隔,所以SpringBoot默认是禁用了矩阵变量的功能
二、如何使矩阵变量功能生效
1、由源码可知WebMvcConfigurer
是一个接口,并且接口里的方法都有默认实现,所以只需重写要修改的方法即可。
2、所以有以下两者方法可以使矩阵变量功能生效:
- 第一种:通过配置类实现
WebMvcConfigurer
接口并且重写configurePathMatch()
方法
@Configuration(proxyBeanMethods = false)
public class WebConfig implements WebMvcConfigurer {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
UrlPathHelper urlPathHelper = new UrlPathHelper();
// 将removeSemicolonContent属性设置为false(不删除分号后内容),使矩阵变量生效
urlPathHelper.setRemoveSemicolonContent(false);
configurer.setUrlPathHelper(urlPathHelper);
}
}
- 第二种:在配置类中通过@Bean注解向容器中添加
WebMvcConfigurer
类型的组件
@Configuration(proxyBeanMethods = false)
public class WebConfig {
@Bean
public WebMvcConfigurer webMvcConfigurer() {
return new WebMvcConfigurer() {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
UrlPathHelper urlPathHelper = new UrlPathHelper();
// 将removeSemicolonContent属性设置为false(不删除分号内容),使矩阵变量生效
urlPathHelper.setRemoveSemicolonContent(false);
configurer.setUrlPathHelper(urlPathHelper);
}
};
}
}
3、浏览器发送 http://localhost:8080/search/cars;low=30;brand=Audi,Benz,BMW
请求,即可看到矩阵变量已经生效
三、若有多个路径变量,并且多个路径变量中具有相同的矩阵变量名时
1、编写Controller业务代码
@RestController
public class ParamTestController {
/**
* 语法:/search/1;age=18/5;age=20
*/
@GetMapping("/search/{tecId}/{stuId}")
public Map searchAge(@MatrixVariable(value = "age", pathVar = "tecId") Integer tecAge,
@MatrixVariable(value = "age", pathVar = "stuId") Integer stuAge) {
Map<String, Object> map = new HashMap<>();
map.put("tecAge", tecAge);
map.put("stuAge", stuAge);
return map;
}
}
2、浏览器发送http://localhost:8080/search/1;age=18/5;age=20
请求
以上为@MatrixVariable
注解的使用!
Q.E.D.