AntPathMatcher的doMatch方法
AntPathMatcher.doMatch(...), 是解决模式匹配的源码
有4个步骤
1. 分解模式字符串, 分解路径字符串
2. 第一个while 循环, 用来判断绝对匹配 /xxx/abc ==> /xxx/abc
3. 第二个while循环两个字符串数组都从最后的下标开始匹配, 直到遇到pattDir为'**'时结束
4. 第三个while循环, 主要解决有多个'**'字符串.djdjdjd**/bc*.class等
// 解决模式匹配的函数, 返回true or false 表示是否匹配
// 参数 pattern: 表示模式字符串
path: 文件的路径
protected boolean doMatch(String pattern, String path, boolean fullMatch, Map<String, String> uriTemplateVariables) {
if (path.startsWith(this.pathSeparator) != pattern.startsWith(this.pathSeparator)) {
return false;
}
1.1. 分解模式字符串
String[] pattDirs = tokenizePattern(pattern);
if (fullMatch && this.caseSensitive && !isPotentialMatch(path, pattDirs)) {
return false;
}
1.2 分解路径字符串
String[] pathDirs = tokenizePath(path);
// pattern的可分配下标 pattIdxStart ~ pattIdxEnd
// path的可分配下标 pathIdxStart ~ pathIdxEnd
int pattIdxStart = 0;
int pattIdxEnd = pattDirs.length - 1;
int pathIdxStart = 0;
int pathIdxEnd = pathDirs.length - 1;
// Match all elements up to the first **
// 2. 第一个while 循环, 用来判断绝对匹配的 /xxx/abc ==> /xxx/abc
// 两个字符串都从下标0开始, 直到模式字符串遇到**结束
while (pattIdxStart <= pattIdxEnd && pathIdxStart <= pathIdxEnd) {
String pattDir = pattDirs[pattIdxStart];
if ("**".equals(pattDir)) {
break;
}
if (!matchStrings(pattDir, pathDirs[pathIdxStart], uriTemplateVariables)) {
return false;
}
pattIdxStart++;
pathIdxStart++;
}
// pathIdxStart > pathIdEnd, 表示文件路径(path), 已经逐一的匹配到了
if (pathIdxStart > pathIdxEnd) {
// 这里返回true 一般是相等的字符串匹配(长度相同)
// /abc/zzzz ==> /abc/zzzz
return true;
}
// 3. 两个字符串数组都从最后的下标开始匹配, 直到遇到pattDir为'**'时结束
while (pattIdxStart <= pattIdxEnd && pathIdxStart <= pathIdxEnd) {
String pattDir = pattDirs[pattIdxEnd];
if (pattDir.equals("**")) {
break;
}
if (!matchStrings(pattDir, pathDirs[pathIdxEnd], uriTemplateVariables)) {
return false;
}
pattIdxEnd--;
pathIdxEnd--;
}
if (pathIdxStart > pathIdxEnd) {
for (int i = pattIdxStart; i <= pattIdxEnd; i++) {
if (!pattDirs[i].equals("**")) {
return false;
}
}
// 这里返回true 一般字符串为
// /xxxx/abcd*.class => /xxxx/abcd /xxx.class
// 即只有一个**, 而且**没发挥到什么作用
// 测试
// AntPathMatcher ant = new AntPathMatcher("/");
//String pattern = "/abc*.class";
//String path = "/abc/ddd.class";
//System.out.println(ant.match(pattern, path));
return true;
}
// 4. 第3个while循环, 主要解决有多个'**'字符串. djdjdjd**/bc*.class等
// 每次下标又从pattIdxStart+1开始
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) {
// '****就跳过, 因为这没有意义, 一个a/ba/ba/ba/ba/ba/ba/ba/b
public AntPathMatcher(String pathSeparator) {
Assert.notNull(pathSeparator, "'pathSeparator' is required");
this.pathSeparator = pathSeparator;
this.pathSeparatorPatternCache = new PathSeparatorPatternCache(pathSeparator);
}
public boolean hasUrl(String url) {
if (url == null || "".equals(url)) {
return false;
}
AntPathMatcher antPathMatcher = new AntPathMatcher();
// 可根据需求做动态匹配
String pattern = "/appexample
匹配(Matches) /app/example, /app/foo/example, 和 /example
/appdir/file.
匹配(Matches) /app/dir/file.jsp, /app/foo/dir/file.html,/app/foo/bar/dir/file.pdf, 和 /app/dir/file.java
*.jsp
匹配(Matches)任何的.jsp 文件
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。