Ant风格路径
maiaimei 2025/10/1 Java
Ant风格路径是一种用于匹配文件路径的模式语言,最初源自Apache Ant构建工具,现在被广泛应用于Java生态系统中,特别是在Spring Framework中。
Ant风格路径的主要规则:
public class AntPathExample {
public static void main(String[] args) {
// 基本通配符:
// ? - matches one character 匹配一个字符
// * - matches zero or more characters 匹配零个或多个字符
// ** - matches zero or more directories in a path 匹配零个或多个目录
// 示例路径模式
String[] patterns = {
"com/t?st.jsp", // 匹配 com/test.jsp, com/tast.jsp
"com/*.jsp", // 匹配 com 目录下的所有 .jsp 文件
"com/**/test.jsp", // 匹配 com 目录及其子目录下的 test.jsp
"org/**/servlet/*.jsp", // 匹配 org 目录下任意层级的 servlet 目录中的 .jsp 文件
"com/{filename:\\w+}.jsp" // 匹配 com 目录下的所有 .jsp 文件,并捕获文件名
};
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
使用Spring的AntPathMatcher:
import org.springframework.util.AntPathMatcher;
public class AntPathMatcherExample {
public static void main(String[] args) {
// The mapping matches URLs using the following rules:
// ? matches one character
// * matches zero or more characters
// ** matches zero or more directories in a path
// {spring:[a-z]+} matches the regexp [a-z]+ as a path variable named "spring"
// Examples:
// com/ t?st. jsp — matches com/ test. jsp but also com/ tast. jsp or com/ txst. jsp
// com/*.jsp — matches all .jsp files in the com directory
// com/**/ test. jsp — matches all test. jsp files underneath the com path
// org/ springframework/**/*.jsp — matches all .jsp files underneath the org/ springframework path
// org/**/ servlet/ bla. jsp — matches org/ springframework/ servlet/ bla. jsp but also org/ springframework/ testing/ servlet/ bla. jsp and org/ servlet/ bla. jsp
// com/{filename:\\w+}.jsp will match com/ test. jsp and assign the value test to the filename variable
AntPathMatcher matcher = new AntPathMatcher();
// 基本匹配
boolean match1 = matcher.match("com/*.jsp", "com/test.jsp");
System.out.println("Match1: " + match1); // true
// 目录匹配
boolean match2 = matcher.match("com/**/test.jsp", "com/sub/test.jsp");
System.out.println("Match2: " + match2); // true
// 提取路径变量
String pattern = "/users/{id}/profile";
String path = "/users/123/profile";
boolean match3 = matcher.match(pattern, path);
System.out.println("Match3: " + match3); // true
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
AntPathMatcher 支持在路径变量中使用正则表达式模式,格式为 {varName:regex}
。其中 varName 可以是任意有效的变量名,不限于 spring。
import org.springframework.util.AntPathMatcher;
import java.util.Map;
public class AntPathMatcherRegexDemo {
private static final AntPathMatcher pathMatcher = new AntPathMatcher();
public static void main(String[] args) {
demonstrateBasicRegexUsage();
demonstrateVariableNames();
demonstrateComplexPatterns();
demonstrateMultipleVariables();
}
// 基本正则表达式用法
private static void demonstrateBasicRegexUsage() {
System.out.println("=== Basic Regex Usage ===");
// 使用不同的变量名
String[] patterns = {
"/user/{spring:[a-z]+}", // 原始示例
"/user/{name:[a-z]+}", // 使用 name 作为变量名
"/user/{id:[a-z]+}", // 使用 id 作为变量名
"/user/{param:[a-z]+}" // 使用 param 作为变量名
};
String path = "/user/john";
for (String pattern : patterns) {
boolean matches = pathMatcher.match(pattern, path);
if (matches) {
Map<String, String> variables =
pathMatcher.extractUriTemplateVariables(pattern, path);
System.out.printf("Pattern: %-20s Variables: %s%n",
pattern, variables);
}
}
}
// 演示不同变量名的使用
private static void demonstrateVariableNames() {
System.out.println("\n=== Variable Names ===");
// 定义模式和路径
String[] patterns = {
"/files/{filename:[a-z]+\\.pdf}",
"/files/{doc:[a-z]+\\.pdf}",
"/files/{file:[a-z]+\\.pdf}"
};
String path = "/files/document.pdf";
for (String pattern : patterns) {
if (pathMatcher.match(pattern, path)) {
Map<String, String> vars =
pathMatcher.extractUriTemplateVariables(pattern, path);
System.out.printf("Pattern: %-25s Variables: %s%n",
pattern, vars);
}
}
}
// 演示复杂的正则表达式模式
private static void demonstrateComplexPatterns() {
System.out.println("\n=== Complex Patterns ===");
// 不同的正则表达式模式
String[] patterns = {
"/users/{userId:[0-9]+}", // 数字ID
"/users/{username:[a-zA-Z][a-zA-Z0-9]+}", // 用户名
"/date/{date:\\d{4}-\\d{2}-\\d{2}}", // 日期格式
"/items/{code:[A-Z]{2}\\d{3}}" // 商品代码
};
// 测试路径
String[] paths = {
"/users/123",
"/users/john123",
"/date/2023-12-25",
"/items/AB123"
};
for (String pattern : patterns) {
for (String path : paths) {
if (pathMatcher.match(pattern, path)) {
Map<String, String> vars =
pathMatcher.extractUriTemplateVariables(pattern, path);
System.out.printf("Pattern: %-30s Path: %-15s Variables: %s%n",
pattern, path, vars);
}
}
}
}
// 演示多个变量的使用
private static void demonstrateMultipleVariables() {
System.out.println("\n=== Multiple Variables ===");
// 包含多个变量的模式
String pattern = "/api/{version:\\d+}/{resource:[a-z]+}/{id:[0-9]+}";
String[] paths = {
"/api/1/users/123",
"/api/2/products/456",
"/api/v1/orders/789" // 这个不会匹配
};
for (String path : paths) {
if (pathMatcher.match(pattern, path)) {
Map<String, String> vars =
pathMatcher.extractUriTemplateVariables(pattern, path);
System.out.printf("Path: %-20s Variables: %s%n", path, vars);
} else {
System.out.printf("Path: %-20s No match%n", path);
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
总结:
- 变量名可以自定义,不限于"spring"
- 正则表达式模式需要用冒号分隔
- 可以在同一路径中使用多个变量
- 正则表达式需要正确转义
- 变量名应遵循Java标识符命名规则