当模式最后一个字符为'/'时,Spring AntPathMatcher的行为会有所不同

时间:2018-06-27 11:53:09

标签: spring spring-mvc

我使用的春季版本是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可以同时匹配patter1和patter2 但是path2仅是数学模式2,而不是模式1,为什么?

1 个答案:

答案 0 :(得分:1)

嗯,您的观点很不错。就是这样(就是这样设计)。

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

为什么matcher.match(patter1, path2)为假 ===> /被视为默认路径分隔符。因此,match方法在内部执行的操作是使用/作为分隔符对其进行拆分,并查看所有令牌是否匹配。但是最后有一条比较线

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

基本上,这将检查模式和路径是否都以/结尾。因此,你越来越虚假。

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

可能是错误。因此,这种情况起作用的原因是由于通配符。