SpringMVC路径匹配规则AntPathMatcher(转)

SpringMVC的路径匹配规则是依照Ant的来的.

实际上不只是SpringMVC,整个Spring框架的路径解析都是按照Ant的风格来的.

在Spring中的具体实现,详情参见 org.springframework.util.AntPathMatcher.

具体规则如下(来自Spring AntPathMatcher源码注释):

 * {@link PathMatcher} implementation for Ant-style path patterns.** <p>Part of this mapping code has been kindly borrowed from <a href="http://ant.apache.org">Apache Ant</a>.** <p>The mapping matches URLs using the following rules:<br>* <ul>* <li>{@code ?} matches one character</li>* <li>{@code *} matches zero or more characters</li>* <li>{@code **} matches zero or more <em>directories</em> in a path</li>* <li>{@code {spring:[a-z]+}} matches the regexp {@code [a-z]+} as a path variable named "spring"</li>* </ul>** <h3>Examples</h3>* <ul>* <li>{@code com/t?st.jsp} &mdash; matches {@code com/test.jsp} but also* {@code com/tast.jsp} or {@code com/txst.jsp}</li>* <li>{@code com/*.jsp} &mdash; matches all {@code .jsp} files in the* {@code com} directory</li>* <li><code>com/&#42;&#42;/test.jsp</code> &mdash; matches all {@code test.jsp}* files underneath the {@code com} path</li>* <li><code>org/springframework/&#42;&#42;/*.jsp</code> &mdash; matches all* {@code .jsp} files underneath the {@code org/springframework} path</li>* <li><code>org/&#42;&#42;/servlet/bla.jsp</code> &mdash; matches* {@code org/springframework/servlet/bla.jsp} but also* {@code org/springframework/testing/servlet/bla.jsp} and {@code org/servlet/bla.jsp}</li>* <li>{@code com/{filename:\\w+}.jsp} will match {@code com/test.jsp} and assign the value {@code test}* to the {@code filename} variable</li>* </ul>** <p><strong>Note:</strong> a pattern and a path must both be absolute or must* both be relative in order for the two to match. Therefore it is recommended* that users of this implementation to sanitize patterns in order to prefix* them with "/" as it makes sense in the context in which they're used.

换成人话就是:

  • ? 匹配1个字符
  • * 匹配0个或多个字符
  • ** 匹配路径中的0个或多个目录
  • {spring:[a-z]+} 将正则表达式[a-z]+匹配到的值,赋值给名为 spring 的路径变量.(PS:必须是完全匹配才行,在SpringMVC中只有完全匹配才会进入controller层的方法)

一个一个的分析.

符号 ?

和其它几个不一样的是,? 要求必须为一个字符,并且不能是代表路径分隔符的/.

@RequestMapping("/index?")
@ResponseBody
public String index(){System.out.println("11");return "11";
}

结果:

index           false 404错误(必须要有一个字符)
index/          false 404错误(不能为"/")
indexab         false 404错误(不能是多个字符)
indexa          true  输出 11

符号 *

*,虽然可以匹配多个任意的字符,但是,如果你以为 * 可以替代 ** 那就错了,* 代表的多个任意字符组成的字符串不能是个 目录 或者说 路径.也就是说,* 并不能拿来替代 **.

示例代码:

@RequestMapping("/index*")
@ResponseBody
public String index(){System.out.println("11");return "11";
}

结果:

index           true  输出 11(可以为0字符)
index/          true  输出 11(可以为"/")
indexa          true  输出 11(可以为1个字符)
indexabc        true  输出 11(可以为多个字符)
index/a         false 404错误("/a"是一个路径)

符号 **

0个或多个目录.** 代表的字符串本身不一定要包含 /

@RequestMapping("/index/**/a")
@ResponseBody
public String index(){System.out.println();return "11";
}

结果:

index/a         true  输出 11(可以为0个目录)
index/x/a       true  输出 11(可以为一个目录)
index/x/z/c/a   true  输出 11(可以为多个目录)

符号 {spring:[a-z]+}

其它的关于 AntPathMatcher 的文章里,对 {spring:[a-z]+} 的匹配大多是只字未提.这里补充下.

示例代码:

@RequestMapping("/index/{username:[a-b]+}")
@ResponseBody
public String index(@PathVariable("username") String username){System.out.println(username);return username;
}

结果:

index/ab        true  输出 ab
index/abbaaa    true  输出 abbaaa
index/a         false 404错误
index/ac        false 404错误

附录(完整测试用例)

节选自 AntPathMatcherTests.不得不说 Spring 的测试用例写的实在是太完善了.

// test exact matching
assertTrue(pathMatcher.match("test", "test"));
assertTrue(pathMatcher.match("/test", "/test"));
assertTrue(pathMatcher.match("http://example.org", "http://example.org")); // SPR-14141
assertFalse(pathMatcher.match("/test.jpg", "test.jpg"));
assertFalse(pathMatcher.match("test", "/test"));
assertFalse(pathMatcher.match("/test", "test"));// test matching with ?'s
assertTrue(pathMatcher.match("t?st", "test"));
assertTrue(pathMatcher.match("??st", "test"));
assertTrue(pathMatcher.match("tes?", "test"));
assertTrue(pathMatcher.match("te??", "test"));
assertTrue(pathMatcher.match("?es?", "test"));
assertFalse(pathMatcher.match("tes?", "tes"));
assertFalse(pathMatcher.match("tes?", "testt"));
assertFalse(pathMatcher.match("tes?", "tsst"));// test matching with *'s
assertTrue(pathMatcher.match("*", "test"));
assertTrue(pathMatcher.match("test*", "test"));
assertTrue(pathMatcher.match("test*", "testTest"));
assertTrue(pathMatcher.match("test/*", "test/Test"));
assertTrue(pathMatcher.match("test/*", "test/t"));
assertTrue(pathMatcher.match("test/*", "test/"));
assertTrue(pathMatcher.match("*test*", "AnothertestTest"));
assertTrue(pathMatcher.match("*test", "Anothertest"));
assertTrue(pathMatcher.match("*.*", "test."));
assertTrue(pathMatcher.match("*.*", "test.test"));
assertTrue(pathMatcher.match("*.*", "test.test.test"));
assertTrue(pathMatcher.match("test*aaa", "testblaaaa"));
assertFalse(pathMatcher.match("test*", "tst"));
assertFalse(pathMatcher.match("test*", "tsttest"));
assertFalse(pathMatcher.match("test*", "test/"));
assertFalse(pathMatcher.match("test*", "test/t"));
assertFalse(pathMatcher.match("test/*", "test"));
assertFalse(pathMatcher.match("*test*", "tsttst"));
assertFalse(pathMatcher.match("*test", "tsttst"));
assertFalse(pathMatcher.match("*.*", "tsttst"));
assertFalse(pathMatcher.match("test*aaa", "test"));
assertFalse(pathMatcher.match("test*aaa", "testblaaab"));// test matching with ?'s and /'s
assertTrue(pathMatcher.match("/?", "/a"));
assertTrue(pathMatcher.match("/?/a", "/a/a"));
assertTrue(pathMatcher.match("/a/?", "/a/b"));
assertTrue(pathMatcher.match("/??/a", "/aa/a"));
assertTrue(pathMatcher.match("/a/??", "/a/bb"));
assertTrue(pathMatcher.match("/?", "/a"));// test matching with **'s
assertTrue(pathMatcher.match("/**", "/testing/testing"));
assertTrue(pathMatcher.match("/*/**", "/testing/testing"));
assertTrue(pathMatcher.match("/**/*", "/testing/testing"));
assertTrue(pathMatcher.match("/bla/**/bla", "/bla/testing/testing/bla"));
assertTrue(pathMatcher.match("/bla/**/bla", "/bla/testing/testing/bla/bla"));
assertTrue(pathMatcher.match("/**/test", "/bla/bla/test"));
assertTrue(pathMatcher.match("/bla/**/**/bla", "/bla/bla/bla/bla/bla/bla"));
assertTrue(pathMatcher.match("/bla*bla/test", "/blaXXXbla/test"));
assertTrue(pathMatcher.match("/*bla/test", "/XXXbla/test"));
assertFalse(pathMatcher.match("/bla*bla/test", "/blaXXXbl/test"));
assertFalse(pathMatcher.match("/*bla/test", "XXXblab/test"));
assertFalse(pathMatcher.match("/*bla/test", "XXXbl/test"));assertFalse(pathMatcher.match("/????", "/bala/bla"));
assertFalse(pathMatcher.match("/**/*bla", "/bla/bla/bla/bbb"));assertTrue(pathMatcher.match("/*bla*/**/bla/**", "/XXXblaXXXX/testing/testing/bla/testing/testing/"));
assertTrue(pathMatcher.match("/*bla*/**/bla/*", "/XXXblaXXXX/testing/testing/bla/testing"));
assertTrue(pathMatcher.match("/*bla*/**/bla/**", "/XXXblaXXXX/testing/testing/bla/testing/testing"));
assertTrue(pathMatcher.match("/*bla*/**/bla/**", "/XXXblaXXXX/testing/testing/bla/testing/testing.jpg"));assertTrue(pathMatcher.match("*bla*/**/bla/**", "XXXblaXXXX/testing/testing/bla/testing/testing/"));
assertTrue(pathMatcher.match("*bla*/**/bla/*", "XXXblaXXXX/testing/testing/bla/testing"));
assertTrue(pathMatcher.match("*bla*/**/bla/**", "XXXblaXXXX/testing/testing/bla/testing/testing"));
assertFalse(pathMatcher.match("*bla*/**/bla/*", "XXXblaXXXX/testing/testing/bla/testing/testing"));assertFalse(pathMatcher.match("/x/x/**/bla", "/x/x/x/"));assertTrue(pathMatcher.match("/foo/bar/**", "/foo/bar")) ;assertTrue(pathMatcher.match("", ""));assertTrue(pathMatcher.match("/{bla}.*", "/testing.html"));    

转载于:https://www.cnblogs.com/hypnotizer/p/7085399.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/269084.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Getting the right Exception Context from a Memory dump Fixed

吃饭回来&#xff0c;看到Share Source CLI团队的rss聚合上面Debug团队的juqiang发了一篇文章&#xff0c;说抓了一个minidump出现了&#xff1a;WARNING: Unable to verify timestamp for mscorwks.dll的错误。上次我在查看一个mini Dump的时候&#xff0c;ntdll.dll好像也出现…

以太网测试工具

以太网是计算机网络的一种局域网技术&#xff0c;多种标准指定了以太网技术的标准&#xff0c;其中包括了物理层、电子信号及基质层协议等多种内容。以太网时目前应用比较广泛的局域网技术。像企业中所用到网络即可成为以太网。那么如果企业中如果网络时长发生延迟、掉帧、断网…

单例模式中饿汉式

写法一&#xff1a; 写法二&#xff1a;

css3 动画的播放、暂停和重新开始

播放 先在keyframes中创建动画&#xff0c;之后把它捆绑到某个选择器&#xff0c;就可以产生动画效果。html <div id"box" class"box"></div> css keyframes mymove {0% {margin-left: 0px;}50% {margin-left: 400px;}100% {margin-left: 0px…

以太网性能测试仪

目前企业办公遇到的首要问题就是网络方面&#xff0c;企业网络中的网络不通、网速慢、丢包、IP地址冲突等各种问题。网络管理人员手里没有趁手的网络故障仪器&#xff0c;解决问题将会非常麻烦。手持式的、口袋型、具备多种测试标准的以太网性能测试仪是先解决企业中网路管理人…

拉斯廷老兄

从前打了一场大仗&#xff0c;大仗结束后&#xff0c;许多士兵被遣散回家。拉斯廷老兄也退役了&#xff0c;他除了一袋干粮和四个金币外一无所有地上路了。圣彼得装成一个可怜的乞丐站在拉斯廷老兄的必经之路上&#xff0c;等他走过来便向他乞讨。拉斯廷老兄回答说&#xff1a;…

极寒极热天气是否可以使用福禄克DSX2-5000网线测试仪工作

当在室外测试网线和光纤时&#xff0c;天气的温度不仅会影响到工作的效率&#xff0c;电缆如果进行拉扯弯折也可能会在安装测试过程中受损。福禄克指定经销商—明辰智航的工程师推荐您了解一下安装测试电缆时的电缆可承受的温度。 在冬天&#xff0c;寒冷的天气致使工作总是不会…

分析uboot中 make xxx_config过程

make xxx_config实质上就是调用了 首先看MKCONFIG&#xff1a; 【注意】SRCTREE源文件下的目录 之后的语句&#xff1a; $(MKCONFIG) $(:_config) arm arm920t EmbedSky NULL s3c2440就相当于执行 #mkconfig xxx arm arm920t EmbedSky NULL s3c2440 #$0 $1 $2 $3 $4 $5 $…

mysql创建索引语句

1:表结构 2:创建索引语句 alter table staffs add index idx_staffs_nameAgePos(NAME,age,pos); 执行后效果

SQL注入法攻击一日通

随着B/S模式应用开发的发展&#xff0c;使用这种模式编写应用程序的程序员也越来越多。但是由于程序员的水平及经验也参差不齐&#xff0c;相当大一部分程序员在编写代码的时候&#xff0c;没有对用户输入数据的合法性进行判断&#xff0c;使应用程序存在安全隐患。用户可以提交…

视频监控存储服务器

现代化社会&#xff0c;无论是安防监控、城市道路监控、IDC机房监控&#xff0c;监控视频都需要多块硬盘进行存储起来。例如像雪亮工程中海量的视频存储到底存储方案是什么&#xff1f;今天航天安网的小编就带你来一探究竟。 雪亮工程是选择了航天安网视频数据智能管理整体解决…

保持饥饿,保持愚蠢

sss 转载于:https://www.cnblogs.com/llljpf/p/7090230.html

网络电话

“宽带电话”电话是一种有别于传统的电话服务。最大的区别在于&#xff0c;它以宽带网线作为通信线路&#xff0c;在不影响您已有的互联网应用的同时&#xff0c;为用户提供优质的电话服务。宽带电话使用非常方便&#xff0c;只需要将电话装置后面的网络接口连接到互联网或者局…

懒汉式,线程不安全

//懒汉式&#xff0c;线程不安全 public class Singleton2 {private static Singleton2 singleton;private Singleton2(){}public static Singleton2 getInstance(){if(singleton null){singleton new Singleton2();}return singleton;}public static void main(String[] ar…

光纤测试时怎么选择对应项目的测试标准及测试仪?

在建造数据中心、办公大楼时采用综合布线认证测试作为验收是必须要做的事。另外我们日常的网络维护、故障诊断也是需要对应的检测方法来帮助我们遇到问题时进行分析和判断问题。光纤测试仪针对不同的测试场景&#xff0c;都是使用什么测试标准呢&#xff1f;福禄克指定经销商—…

VueJS定义组件规则

Vue.js 组件组件&#xff08;Component&#xff09;是 Vue.js 最强大的功能之一&#xff0c;组件可以扩展 HTML 元素&#xff0c;封装可重用的代码。组件系统让我们可以用独立可复用的小组件来构建大型应用&#xff0c;几乎任意类型的应用的界面都可以抽象为一个组件树&#xf…

文件编码

在网站开发中&#xff0c;js文件通常要用utf8来保存才可以引入asp.net中&#xff0c;否则windows系统认不出来。windows系统的文本文件格式有几种utf8、ansi&#xff08;在中文操作系统中的gb2312使用此名称&#xff09;、等等&#xff0c;通常的文件传输都使用utf8。string类对…

企业中的局域网性能应该怎么得到保障?

如果提到局域网&#xff0c;我们首先想到的是&#xff0c;他的覆盖面积可以达到几千米之内。因为安装简单、费用低、现有向外扩展等多处优点&#xff0c;在各类企业办公地点运用比较广泛。局域网的好处就不用说了&#xff0c;而在使用局域网过程中&#xff0c;维护企业中的局域…

焊接件技术要求怎么写_钣金焊接件生锈了怎么办

相信很多厂家或企业都被钣金焊接件生锈的问题困扰过&#xff0c;打磨掉以后又会生锈&#xff0c;长期以往&#xff0c;不仅很耗人力物力&#xff0c;对工件本身的磨损也是严重的。那有没有一种更先进除锈方式可以更好的解决这一问题呢&#xff1f;答案是确定的。青工 机械研发的…