首页 > 解决方案 > 当模式最后一个字符为“/”时,Spring AntPathMatcher 的行为不同

问题描述

我使用的 spring 版本是 4.3.7-SNAPSHOT 并且默认路径分隔符是/

我发现当模式字符串最后一个字符是' / ',而路径字符串最后一个字符不是' / '时,AntPathMatcher 的行为不同,请看下面的代码

public class AntPathMatcher4SpringTest {

private AntPathMatcher matcher = new AntPathMatcher();

@Test
public void test1() {     
    String patter1 = "/com/abc/def/x.html/";
    String patter2 = "/com/**/abc/def/x.html/";
    String path1 = "/com/abc/def/x.html/";
    String path2 = "/com/abc/def/x.html";

    assertTrue(matcher.match(patter1, path1));
    assertTrue(matcher.match(patter2, path1));
    assertFalse(matcher.match(patter1, path2));
    assertTrue(matcher.match(patter2, path2));
  }
}

而patter1和patter2的最后一个字符都是' / ',而path1的最后一个字符也是' / ',但path2不是。

path1 可以匹配模式 1 和模式 2,但路径 2 只能匹配数学模式 2,而不是模式 1,为什么?

标签: springspring-mvc

解决方案


嗯,你提出了一个非常好的观点。它就是这样(这就是它的设计方式)。

但也许我可以提供一些内部细节。这是我调试后发现的AntPathMatcher::match

matcher.match(patter1, path2)为 false ===>的原因/被视为默认路径分隔符。所以match内部做的方法是将它/用作分隔符并查看所有标记是否匹配。但最后有这样一条对比线

return (pattern.endsWith(this.pathSeparator) == path.endsWith(this.pathSeparator));  

这基本上是检查模式和路径是否都以/或不结束。因此,您变得虚假。

matcher.match(patter2, path2)正确的原因 ===> 当涉及通配符时,事情会变得很棘手 **。如果涉及通配符,则逻辑是这样的,最初匹配令牌直到**遇到。一旦找到,它会检查从最后一次到最后一次出现的令牌**。在这种情况下,不检查尾随/。这是它起作用的主要原因。

可能是一个错误。所以这种情况起作用的原因是通配符。


推荐阅读