就像名字提示的那样,路径模式是使用了Apache Ant的样式路径,Apache Ant样式的路径有三种通配符匹配方法。
通配符 | 描述 |
? | 匹配任何单字符 |
* | 匹配0或者任意数量的字符 |
** | 匹配0或者更多的目录 |
使用方法比较简单,如下:
public static void main(String[] args){ AntPathMatcher matcher = new AntPathMatcher(); System.out.println(matcher.match("/**", "/resources/css/base.css")); System.out.println(matcher.match("**", "test/test1/test/2/test.jsp")); System.out.println(matcher.match("**", "/test/test1/test/2/test.jsp/")); }
输出
true true false
贴上源码
protected boolean doMatch(String pattern, String path, boolean fullMatch, Map<String, String> uriTemplateVariables) { if (path.startsWith(this.pathSeparator) != pattern.startsWith(this.pathSeparator)) { return false; } String[] pattDirs = StringUtils.tokenizeToStringArray(pattern, this.pathSeparator, this.trimTokens, true); String[] pathDirs = StringUtils.tokenizeToStringArray(path, this.pathSeparator, this.trimTokens, true); int pattIdxStart = 0; int pattIdxEnd = pattDirs.length - 1; int pathIdxStart = 0; int pathIdxEnd = pathDirs.length - 1; // Match all elements up to the first ** while (pattIdxStart <= pattIdxEnd && pathIdxStart <= pathIdxEnd) { String patDir = pattDirs[pattIdxStart]; if ("**".equals(patDir)) { break; } if (!matchStrings(patDir, pathDirs[pathIdxStart], uriTemplateVariables)) { return false; } pattIdxStart++; pathIdxStart++; } if (pathIdxStart > pathIdxEnd) { // Path is exhausted, only match if rest of pattern is * or **'s if (pattIdxStart > pattIdxEnd) { return (pattern.endsWith(this.pathSeparator) ? path.endsWith(this.pathSeparator) : !path.endsWith(this.pathSeparator)); } if (!fullMatch) { return true; } if (pattIdxStart == pattIdxEnd && pattDirs[pattIdxStart].equals("*") && path.endsWith(this.pathSeparator)) { return true; } for (int i = pattIdxStart; i <= pattIdxEnd; i++) { if (!pattDirs[i].equals("**")) { return false; } } return true; } else if (pattIdxStart > pattIdxEnd) { // String not exhausted, but pattern is. Failure. return false; } else if (!fullMatch && "**".equals(pattDirs[pattIdxStart])) { // Path start definitely matches due to "**" part in pattern. return true; } // up to last '**' while (pattIdxStart <= pattIdxEnd && pathIdxStart <= pathIdxEnd) { String patDir = pattDirs[pattIdxEnd]; if (patDir.equals("**")) { break; } if (!matchStrings(patDir, pathDirs[pathIdxEnd], uriTemplateVariables)) { return false; } pattIdxEnd--; pathIdxEnd--; } if (pathIdxStart > pathIdxEnd) { // String is exhausted for (int i = pattIdxStart; i <= pattIdxEnd; i++) { if (!pattDirs[i].equals("**")) { return false; } } return true; } while (pattIdxStart != pattIdxEnd && pathIdxStart <= pathIdxEnd) { int patIdxTmp = -1; for (int i = pattIdxStart + 1; i <= pattIdxEnd; i++) { if (pattDirs[i].equals("**")) { patIdxTmp = i; break; } } if (patIdxTmp == pattIdxStart + 1) { // '**/**' situation, so skip one pattIdxStart++; continue; } // Find the pattern between padIdxStart & padIdxTmp in str between // strIdxStart & strIdxEnd int patLength = (patIdxTmp - pattIdxStart - 1); int strLength = (pathIdxEnd - pathIdxStart + 1); int foundIdx = -1; strLoop: for (int i = 0; i <= strLength - patLength; i++) { for (int j = 0; j < patLength; j++) { String subPat = pattDirs[pattIdxStart + j + 1]; String subStr = pathDirs[pathIdxStart + i + j]; if (!matchStrings(subPat, subStr, uriTemplateVariables)) { continue strLoop; } } foundIdx = pathIdxStart + i; break; } if (foundIdx == -1) { return false; } pattIdxStart = patIdxTmp; pathIdxStart = foundIdx + patLength; } for (int i = pattIdxStart; i <= pattIdxEnd; i++) { if (!pattDirs[i].equals("**")) { return false; } } return true; }
版权声明:本文为博主原创文章,未经博主允许不得转载。