URL匹配之AntPathMatcher

Posted justry_deng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了URL匹配之AntPathMatcher相关的知识,希望对你有一定的参考价值。

URL匹配之AntPathMatcher

背景说明

Ant匹配模式是当下(2022-03-18)最火的对URL进行匹配的模式。很多框架都采用AntURL进行匹配,如Spring框架中的org.springframework.util.AntPathMatcher

Ant基础通配符简介

通配符介绍示例说明
?匹配1个字符模板:/jd/a?c
匹配示例:/jd/abc
不匹配示例1:/jd/ac
不匹配示例2:/jd/axyzc
*匹配>=0个字符模板:/jd/a*c
匹配示例1:/jd/ac
匹配示例2:/jd/abc
匹配示例3:/jd/axyzc
不匹配示例1:/jd/a
不匹配示例2:/jd/xc
不匹配示例3:/jk/ac
**匹配>=0个目录示例1:/**/abc.html匹配所有以abc.html结尾的路径
示例2:/abc/**匹配所有以/abc/打头的路径
示例3:abc**匹配所有以abc打头的路径
示例4:/xyz/**/qwer匹配所有以/xyz/打头并以/qwer结尾的路径

AntPathMatcher常用方法介绍及示例

提示:以下内容基于spring 5.3.12

常用的构造方法

  • 示例

    // 无参构造,默认以 "/" 作为路径分隔符
    AntPathMatcher antPathMatcher = new AntPathMatcher();
    // 也可以指定路径分隔符
    antPathMatcher = new AntPathMatcher("-");
    

extractUriTemplateVariables(String pattern, String path):根据pattern的规则,从path中抽取对应的变量值

当pattern与path不匹配时,会报错

  • 示例一

    AntPathMatcher antPathMatcher = new AntPathMatcher();
    Map<String, String> map = antPathMatcher.extractUriTemplateVariables("/root/a/b/c/d.html", "/root/aa/bb/cc/xyz.html");
    map.forEach((k, v) -> System.out.println(k + "=" + v));
    

    输出

    a=aa
    b=bb
    c=cc
    d=xyz
    
  • 示例二

    AntPathMatcher antPathMatcher = new AntPathMatcher();
    Map<String, String> map = antPathMatcher.extractUriTemplateVariables("/root/a/b/c", "/root/aa/bb/cc/xyz.html");
    map.forEach((k, v) -> System.out.println(k + "=" + v));
    

    输出

    Exception in thread "main" java.lang.IllegalStateException: Pattern "/root/a/b/c" is not a match for "/root/aa/bb/cc/xyz.html"
    	at org.springframework.util.AntPathMatcher.extractUriTemplateVariables(AntPathMatcher.java:517)
    	at com.example.springbootdemo.MainApplication.main(MainApplication.java:17)
    

isPattern(String str):判断str是否可以作为一个pattern匹配器

注:当str是一个不带任何通配符(如:?***等)的字符串,即:str是一个准确的字符串时。此方法返回false,该方法认为:既然pattern是一个不带通配符的明确字符串,那么你直接和要匹配的path进行相等比较即可

  • 示例一

    AntPathMatcher antPathMatcher = new AntPathMatcher();
    boolean isPattern = antPathMatcher.isPattern("/aa/bb/cc/xyz.html");
    System.out.println(isPattern);
    

    输出

    false
    
  • 示例二

    AntPathMatcher antPathMatcher = new AntPathMatcher();
    boolean isPattern = antPathMatcher.isPattern("/aa/*/cc/xyz.html");
    System.out.println(isPattern);
    

    输出

    true
    
    
  • 示例三

    AntPathMatcher antPathMatcher = new AntPathMatcher();
    boolean isPattern = antPathMatcher.isPattern("/aa/**/xyz.html");
    System.out.println(isPattern);
    
    

    输出

    true
    
    
  • 示例四

    AntPathMatcher antPathMatcher = new AntPathMatcher();
    boolean isPattern = antPathMatcher.isPattern("/aa/?/xyz.html");
    System.out.println(isPattern);
    
    

    输出

    true
    
    
  • 示例五

    AntPathMatcher antPathMatcher = new AntPathMatcher();
    boolean isPattern = antPathMatcher.isPattern("/aa/qwer/xyz.html");
    System.out.println(isPattern);
    
    

    输出

    true
    
    

match(String pattern, String path):path是否完全匹配pattern

  • 示例一(示例统配符?

    AntPathMatcher antPathMatcher = new AntPathMatcher();
    // 输出:true
    System.out.println(antPathMatcher.match("/jd/a?c", "/jd/abc"));
    // 输出:false
    System.out.println(antPathMatcher.match("/jd/a?c", "/jd/ac"));
    // 输出:false
    System.out.println(antPathMatcher.match("/jd/a?c", "/jd/axyzc"));
    
    
  • 示例二(示例统配符*

    AntPathMatcher antPathMatcher = new AntPathMatcher();
    // 输出:true
    System.out.println(antPathMatcher.match("/jd/a*c", "/jd/ac"));
    // 输出:true
    System.out.println(antPathMatcher.match("/jd/a*c", "/jd/abc"));
    // 输出:true
    System.out.println(antPathMatcher.match("/jd/a*c", "/jd/axyzc"));
    // 输出:false
    System.out.println(antPathMatcher.match("/jd/a*c", "/jd/a"));
    // 输出:false
    System.out.println(antPathMatcher.match("/jd/a*c", "/jd/xc"));
    // 输出:false
    System.out.println(antPathMatcher.match("/jd/a*c", "/jk/ac"));
    
    
  • 示例三(示例统配符**

    AntPathMatcher antPathMatcher = new AntPathMatcher();
    //true
    //false
    //false
    System.out.println(antPathMatcher.match("**", ""));
    System.out.println(antPathMatcher.match("**", "/"));
    System.out.println(antPathMatcher.match("**", ""));
    
    //false
    //true
    //true
    System.out.println(antPathMatcher.match("/**", ""));
    System.out.println(antPathMatcher.match("/**", "/"));
    System.out.println(antPathMatcher.match("/**", ""));
    
    //true
    //false
    //false
    System.out.println(antPathMatcher.match("**/", ""));
    System.out.println(antPathMatcher.match("**/", "/"));
    System.out.println(antPathMatcher.match("**/", ""));
    
    //false
    //true
    //true
    System.out.println(antPathMatcher.match("/**/", ""));
    System.out.println(antPathMatcher.match("/**/", "/"));
    System.out.println(antPathMatcher.match("/**/", ""));
    
    //true
    //true
    //true
    //true
    //false
    //false
    System.out.println(antPathMatcher.match("/**/abc.html", "/abc.html"));
    System.out.println(antPathMatcher.match("/**/abc.html", "//abc.html"));
    System.out.println(antPathMatcher.match("/**/abc.html", "/1/2/3/4/5/abc.html"));
    System.out.println(antPathMatcher.match("/**/abc.html", "/a/b/c//jd/ac/abc.html"));
    System.out.println(antPathMatcher.match("/**/abc.html", "/a/abc"));
    System.out.println(antPathMatcher.match("/**/abc.html", "/a/bc.html"));
    
    
  • 示例四(示例占位符

    AntPathMatcher antPathMatcher = new AntPathMatcher();
    //true
    //false
    //false
    System.out.println(antPathMatcher.match("a/b/c", "a/b0/c"));
    System.out.println(antPathMatcher.match("a/b/c", "a/b1/b2/b3/c"));
    System.out.println(antPathMatcher.match("a/b", "a/b1/b2/b3/c"));
    
    

matchStart(String pattern, String path):pattern的前面一部分是否就能匹配上整个path

注:若path与pattern完全匹配,那么也算:pattern的前面一部分匹配上了整个path

注:可理解为,path是pattern的一个子集

  • 示例

    AntPathMatcher antPathMatcher = new AntPathMatcher();
    //false
    //true
    //true
    System.out.println(antPathMatcher.matchStart("a/b", "a/b0/c"));
    System.out.println(antPathMatcher.matchStart("a/b/c", "a/b0/c"));
    System.out.println(antPathMatcher.matchStart("a/b/c/d", "a/b0/c"));
    
    //false
    //true
    //true
    System.out.println(antPathMatcher.matchStart("a/?", "a/b/c"));
    System.out.println(antPathMatcher.matchStart("a/?/c", "a/b/c"));
    System.out.println(antPathMatcher.matchStart("a/?/c/d", "a/b/c"));
    
    //false
    //true
    //true
    System.out.println(antPathMatcher.matchStart("a/*", "a/b0/c"));
    System.out.println(antPathMatcher.matchStart("a/*/c", "a/b0/c"));
    System.out.println(antPathMatcher.matchStart("a/*/c/d", "a/b0/c"));
    
    //true
    //true
    //true
    System.out.println(antPathMatcher.matchStart("a/**", "a/b0/c"));
    System.out.println(antPathMatcher.matchStart("a/**/c", "a/b0/c"));
    System.out.println(antPathMatcher.matchStart("a/**/c/d", "a/b0/c"));
    
    

^_^ 如有不当之处,欢迎指正
^_^ 本文已经被收录进《程序员成长笔记》 ,笔者JustryDeng

以上是关于URL匹配之AntPathMatcher的主要内容,如果未能解决你的问题,请参考以下文章

Spring之AntPathMatcher

Path的Pattern匹配:前缀树与Spring AntPathMatcher

AntPathMatcher路径匹配器

AntPathMatcher路径匹配器

AntPathMatcher做路径匹配

Spring专题「技术原理」为大家介绍一下Spring中的Ant路径匹配工具组件AntPathMatcher