spring中的AntPathMatcher路径匹配规则

antPathMatcher用法:

使用通配符进行匹配

  • ?匹配一个字符(matches one character)。
  • *  匹配0个或者多个字符 ( matches zero or more characters)。
  • ** 匹配url中的0个或多个子目录 (matches zero or more directories in a path)
  • {spring:[a-z]+} 匹配满足正则表达式[a-z]+的路径,这些路径赋值给变量"spring" (matches the regexp [a-z]+ as a path variable named "spring")

用例:

1. /erb/contract/?est.json 匹配/erb/contract/test.json、/erb/contract/aest.json、/erb/contract/best.json, 但不匹配/erb/contract/est.json ;

2. /erb/contract/*.json 匹配以.json的路径,/erb/contract/a.json、/erb/contract/ab.json、/erb/contract/abcXXX.json

3. /erb/contract/*  匹配以 /erb/contract/开始的路径,但只能是一级,/erb/contract/a、/erb/contract/abXXX、/erb/contract/a.json、/erb/contract/abXX.json、/erb/contract/a.do、/erb/contract/abXX.do 等

4.  /**/contract/** ,只要路径含有contract就可以匹配,比如:/erb/XXX/contract/a/b/XX、/erb/XXX/contract/a/b/XX.XX 

5. /**/{contract:[a-z,A-Z]+}/**, 比如:/erb/XXX/contract/a/b/XX、/erb/XXX/contractXXX/a/b/XX.XX

long begin = System.currentTimeMillis();
AntPathMatcher antPathMatcher = new AntPathMatcher();

boolean match = antPathMatcher.match("/**/contract/digital/view/info*/**",
    "/erb/contract/digital/view/info.json?signatureEncode=XXXXXXXXXX");

System.out.println(String.format("match:%s, 耗时:%d", match, (System.currentTimeMillis()-begin)));


boolean match1 = antPathMatcher.match("/erb/contract/?est.json", "/erb/contract/test.json");
System.out.println(String.format("match1:%s, ", match1));

long begin2 = System.currentTimeMillis();
boolean match2 = antPathMatcher.match("/**/contract/digital/view/info",
    "/org/contract/digital/view/info");
System.out.println(String.format("match2:%s, 耗时:%d,", match2, (System.currentTimeMillis()-begin2)));

boolean match3 = antPathMatcher.match("/erb/contract/*.json", "/erb/contract/XXX.json");
System.out.println(String.format("match3:%s ", match3));

boolean match4 = antPathMatcher.match("/erb/contract/**", "/erb/contract/XXX.XX");
System.out.println(String.format("match4:%s ", match4));

boolean match5 = antPathMatcher.match("/**/contract/**", "/XXX/XXX/contract/XXX/XX.XX");
System.out.println(String.format("match5:%s ", match5));
boolean match6 = antPathMatcher.match("/**/{contract:[a-z,A-Z]+}/**", "/XXX/XXX/contractXXX/XXX/XX.XX");
System.out.println(String.format("match6:%s, 总耗时:%d", match6,(System.currentTimeMillis()-begin)));

测试结果:

match:true, 耗时:9
match1:true, 
match2:true, 耗时:0,
match3:true 
match4:true 
match5:true 
match6:true, 总耗时:12

AntPathMatcher提供了丰富的API,主要以match()matchStart()为主,这二者都是调用doMatch()保护方法,AntPathMatcher单次计算是比较耗时的,但antPathMatcher使用了两个Map对象做了缓存,路径缓存stringMatcherCache和分词缓存tokenizedPatternCache,缓存初始大小为256,最大为65536;

tokenizedPatternCache用于存放正则规则和其对应的分词,key:正则表达式,vlaue:是正则表达式分词后的分词String[] tokenized,正则规则默认以'/'进行分词,分词符默认是'/',分词符可以通过pathSeparator自行指定。

stringMatcherCache待匹配路径缓存,原理和缓存规则同tokenizedPatternCache,key:正则表达式分词后的分词,value:是其对应的AntPathStringMatcher对象,每个AntPathStringMatcher对应一个Pattern

注意下,这里缓存有个问题:两个cache的数量都不能超过65536,有其中任意一个cache超过这个限制,则会清空整个cache,并且会把缓存匹配标识Boolean cachePatterns置为false;自此之后,规则分词缓存和分词对应的Matcher缓存 都会失效失效,每次都会重新分词,重新创建内部类AntPathStringMatcher(其本质是个pattern),不知设计者是故意为之,还是设计者没有考虑到;但一般常规网站或系统的请求路径很少能达到65536 这个上限的。


 

 

 

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值