SpringBoot @MatrixVariable注解 矩阵变量

下面我们来看一个请求

/cars/{path;low=34;brand=byd,aodi,bc}

以 ; 结尾的请求就是矩阵变量

有这样一个面试题,页面开发,如果把cookie 禁用掉,session 里面的内容怎么找到

  • cookie 和 session 的机制就是,session里面保存一个k-v的值,然后每个人都有一个jsessionid,这个jsessionid 会被保存在cookie里面,每次用户发送请求cookie 都会携带jsessionid ,如果把cookie 禁用掉,我们要获取session 的k获取v ,肯定要通过jsessionid来拿到这个session对象,但是jsession有保存在cookie 所以无法从session对象的v
  • 这里我们可以使用 矩阵变量来获取 session 如 /user;jessionid=xxx   用过url 重写,把cookie的值使用矩阵变量的方式进行传递

如下有这样一个请求

前端

<a href="/cars/sales;low=23;brand=byd,ad,bc">矩阵变量</a>

后台处理控制器


    @GetMapping(value = "/cars/sales")
    public String cars(@MatrixVariable("low") Integer low,
                       @MatrixVariable("brand") List<String> brands) {
        return "low = " + low + "--- brands=" + brands;
    }

运行测试结果

Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.

Fri Mar 26 13:56:23 CST 2021
There was an unexpected error (type=Bad Request, status=400).
Missing matrix variable 'low' for method parameter of type Integer
org.springframework.web.bind.MissingMatrixVariableException: Missing matrix variable 'low' for method parameter of type Integer
  1. 错误的原因 springboot 默认是禁用了矩阵变量的功能,我们需要手动开启,这就需要我们定制化springboot的组件

源码解读

WebMvcAutoConfiguration 类的 configurePathMatch方法内部有这样一个处理

		@Override
		public void configurePathMatch(PathMatchConfigurer configurer) {
			if (this.mvcProperties.getPathmatch()
					.getMatchingStrategy() == WebMvcProperties.MatchingStrategy.PATH_PATTERN_PARSER) {
				configurer.setPatternParser(new PathPatternParser());
			}
			configurer.setUseSuffixPatternMatch(this.mvcProperties.getPathmatch().isUseSuffixPattern());
			configurer.setUseRegisteredSuffixPatternMatch(
					this.mvcProperties.getPathmatch().isUseRegisteredSuffixPattern());
			this.dispatcherServletPath.ifAvailable((dispatcherPath) -> {
				String servletUrlMapping = dispatcherPath.getServletUrlMapping();
				if (servletUrlMapping.equals("/") && singleDispatcherServlet()) {
					UrlPathHelper urlPathHelper = new UrlPathHelper();
					urlPathHelper.setAlwaysUseFullPath(true);
					configurer.setUrlPathHelper(urlPathHelper);
				}
			});
		}
  • UrlPathHelper urlPathHelper = new UrlPathHelper(); 创建了一个UrlPathHelper 进行解析 其中在 UrlPathHelper类中有这样一个属性 removeSemicolonContent 默认为true 这个属性的意思就是 要不要移除分号内容
  • 所以我们要自定义有以下2种写法 1是实现 WebMvcConfigurer 的 configurePathMatch  2是 @Bean 的方式给容器放入一个WebMvcConfigurer

这里我主要使用实现 WebMvcConfigurer 的方式

新增配置类  MyConfiguration 代码如下

@Configuration(proxyBeanMethods = false) //每次从容器中获取bean 是否为同一个 如果为false 则每次获取的实例都是不同的
public class MyConfiguration  implements WebMvcConfigurer {

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        UrlPathHelper urlPathHelper = new UrlPathHelper();
        //不移除举证变量后面的内容
        urlPathHelper.setRemoveSemicolonContent(false);
        urlPathHelper.setAlwaysUseFullPath(true);
        configurer.setUrlPathHelper(urlPathHelper);
    }
}

我们加入配置文件后再次访问这个请求运行如下

Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.

Fri Mar 26 14:15:18 CST 2021
There was an unexpected error (type=Not Found, status=404).
No message available
  • 这次发现404 没有找到这个请求,这个主要是因为 矩阵变量主要绑定在 路径变量上的
  • 修改 控制器里面的代码如下
    @GetMapping(value = "/cars/{path}")
    public String cars(@MatrixVariable("low") Integer low,
                       @MatrixVariable("brand") List<String> brands,
                       @PathVariable("path") String path) {
        return "low = " + low + "--- brands=" + brands + "----path=" + path;
    }

再次测试如下

low = 23--- brands=[byd, ad, bc]----path=sales
  • 成功从控制器拿到响应的数据

扩展

如果请求为 user/1;age=20/2;age=40 这样的请求后台如何进行处理呢

前端请求

<a href="user/1;age=20/2;age=40">矩阵变量2</a>

后台处理器

    @GetMapping("/user/{boosId}/{empid}")
    public String getUser1(@MatrixVariable(value = "age", pathVar = "boosId") Integer boosId,
                           @MatrixVariable(value = "age", pathVar = "empid") Integer empid) {
        return "get user boosId=" + boosId + "----empid=" + empid;
    }
  • 使用 MatrixVariable 的 pathVar 来确认这个请求到底是第一个参数的age 还是第二个参数的age 使用 pathVar 和 val 的名称来唯一确认一个值
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值