程序地带

SpringBoot魔法堂:@MatrixVariable参数注解使用详解


前言

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 是否为必填值,默认为false
defaultValue 设置默认值

其中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


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/fsjohnhuang/p/14284988.html

随机推荐

c++ string 回文串_聊聊算法回文字符串

c++ string 回文串_聊聊算法回文字符串

我这天天写核心业务的人,都没用什么算法啊!其实算法无处不在,栈队列树链表都包含算法思想,算法并不是单纯指用代码解决那些深奥难懂的数学逻辑问题&#...

weixin_39791349 阅读(282)

Python按行读文件

1.最基本的读文件方法:#File:readline-example-1.pyfile=open("sample.txt")while1:line=fil...

于小勇 阅读(924)

Spring Boot实战(一)--集成ElasticSearch

1ElasticSearch简单使用1简介Lucene是一个信息检索工具包,不包含搜索引擎系统。包含索引结构、读写索引的工具、排序,搜索规则等工具类。ElasticSear...

zzw_pro 阅读(243)

深入理解k8s调度器与调度框架核心源码

k8s调度器kube-scheduler的核心实现在pkg/scheduler下algorithmprovider:调度算法的注册与获取功能,核心数据结构是一个字典类的结构apis:k8s集群中的资源...

扬羽流风 阅读(119)

XML学习

基础概念XML是可扩展标记语言(独立于软件和硬件的信息传输工具)用途为存储和传输数据XML标签需自行定义,标签的意义依赖于软件和程序的功能特性与HTML的区别...

硬核小青年 阅读(974)

STL源码分析——第五章 关联式容器

STL源码分析——第五章 关联式容器

红黑树(set、map、multiset、multimap的底层机制实现)每个节点不是红色就是黑色。根节点为黑色。如果节点为红,其子节点必须为黑。任一节点至N...

沟沟沟 阅读(106)

Java:集合的总结(二)

Java集合的总结:二泛型概述:格式:注意:优点:由来:泛型类:泛型方法:泛型接口&#x...

zjd真可爱 阅读(487)

Kubernetes1.19.4安装Rook1.5

目录一、rook简介二、rook部署集群环境磁盘规划拉取项目部署RookOperator获取镜像配置cluster部署cluster部署Toolbox测试Rookrook卸载三、存储3.1ceph块存...

无言的苍凉 阅读(575)