org.springframework.util.AntPathMatcher 工具类

来源:互联网 发布:英语6级网络课程 编辑:程序博客网 时间:2024/06/05 00:41

org.springframework.util.AntPathMatcher 工具类

2017-01-10 今天用到了 AntPathMatcher 来匹配url的路径。
AntPathMatcher 是spring中的一个工具类,通过使用通配符的方式来匹配路径。
通配符有三种:

  • ?:匹配任意单个字符
  • *:匹配任意数量的字符,不包括“/”
  • **:匹配更多的目录,包括“/”

以下是 AntPathMatcher 的核心代码:

private static final Pattern VARIABLE_PATTERN = Pattern.compile("\\{[^/]+?\\}");/** Default path separator: "/" */public static final String DEFAULT_PATH_SEPARATOR = "/";private String pathSeparator = DEFAULT_PATH_SEPARATOR;/** Set the path separator to use for pattern parsing. Default is "/", as in Ant. */public void setPathSeparator(String pathSeparator) {    this.pathSeparator = (pathSeparator != null ? pathSeparator : DEFAULT_PATH_SEPARATOR);}/** * Actually match the given <code>path</code> against the given <code>pattern</code>. * @param pattern the pattern to match against * @param path the path String to test * @param fullMatch whether a full pattern match is required (else a pattern match * as far as the given base path goes is sufficient) * @return true if the supplied path matched, false if it didn't */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);    String[] pathDirs = StringUtils.tokenizeToStringArray(path, this.pathSeparator);    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;}/** * Tests whether or not a string matches against a pattern. The pattern may contain two special characters:<br> '*' * means zero or more characters<br> '?' means one and only one character * @param pattern pattern to match against. Must not be <code>null</code>. * @param str string which must be matched against the pattern. Must not be <code>null</code>. * @return true if the string matches against the pattern, or false otherwise. */private boolean matchStrings(String pattern, String str, Map<String, String> uriTemplateVariables) {    AntPathStringMatcher matcher = new AntPathStringMatcher(pattern, str, uriTemplateVariables);    return matcher.matchStrings();}
0 0
原创粉丝点击