Skip to content

Commit ed98bf0

Browse files
committed
SPR-5812 - Custom regex matching for @PathVariable
1 parent 0096930 commit ed98bf0

File tree

2 files changed

+34
-7
lines changed

2 files changed

+34
-7
lines changed

org.springframework.core/src/main/java/org/springframework/util/AntPatchStringMatcher.java

+20-7
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@
2323
import java.util.regex.Pattern;
2424

2525
/**
26-
* Package-protected helper class for {@link AntPathMatcher}.
27-
* Tests whether or not a string matches against a pattern using a regular expression.
26+
* Package-protected helper class for {@link AntPathMatcher}. Tests whether or not a string matches against a pattern
27+
* using a regular expression.
2828
*
29-
* <p>The pattern may contain special characters: '*' means zero or more characters;
30-
* '?' means one and only one character; '{' and '}' indicate a URI template pattern.
29+
* <p>The pattern may contain special characters: '*' means zero or more characters; '?' means one and only one
30+
* character; '{' and '}' indicate a URI template pattern.
3131
*
3232
* @author Arjen Poutsma
3333
* @since 3.0
@@ -36,6 +36,8 @@ class AntPatchStringMatcher {
3636

3737
private static final Pattern GLOB_PATTERN = Pattern.compile("\\?|\\*|\\{([^/]+?)\\}");
3838

39+
private static final String DEFAULT_VARIABLE_PATTERN = "(.*)";
40+
3941
private final Pattern pattern;
4042

4143
private String str;
@@ -65,13 +67,24 @@ else if ("*".equals(match)) {
6567
patternBuilder.append(".*");
6668
}
6769
else if (match.startsWith("{") && match.endsWith("}")) {
68-
patternBuilder.append("(.*)");
69-
variableNames.add(m.group(1));
70+
int colonIdx = match.indexOf(':');
71+
if (colonIdx == -1) {
72+
patternBuilder.append(DEFAULT_VARIABLE_PATTERN);
73+
variableNames.add(m.group(1));
74+
}
75+
else {
76+
String variablePattern = match.substring(colonIdx + 1, match.length() - 1);
77+
patternBuilder.append('(');
78+
patternBuilder.append(variablePattern);
79+
patternBuilder.append(')');
80+
String variableName = match.substring(1, colonIdx);
81+
variableNames.add(variableName);
82+
}
7083
}
7184
end = m.end();
7285
}
7386
patternBuilder.append(quote(pattern, end, pattern.length()));
74-
return Pattern.compile(patternBuilder.toString());
87+
return Pattern.compile(patternBuilder.toString());
7588
}
7689

7790
private String quote(String s, int start, int end) {

org.springframework.core/src/test/java/org/springframework/util/AntPathMatcherTests.java

+14
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,20 @@ public void extractUriTemplateVariables() throws Exception {
334334
assertEquals(expected, result);
335335
}
336336

337+
@Test
338+
public void extractUriTemplateVariablesCustomRegex() {
339+
Map<String, String> result = pathMatcher
340+
.extractUriTemplateVariables("{symbolicName:[\\w\\.]+}-{version:[\\w\\.]+}.jar",
341+
"com.example-1.0.0.jar");
342+
assertEquals("com.example", result.get("symbolicName"));
343+
assertEquals("1.0.0", result.get("version"));
344+
345+
result = pathMatcher.extractUriTemplateVariables("{symbolicName:[\\w\\.]+}-sources-{version:[\\w\\.]+}.jar",
346+
"com.example-sources-1.0.0.jar");
347+
assertEquals("com.example", result.get("symbolicName"));
348+
assertEquals("1.0.0", result.get("version"));
349+
}
350+
337351
@Test
338352
public void combine() {
339353
assertEquals("", pathMatcher.combine(null, null));

0 commit comments

Comments
 (0)