#1455 - Fix template variable cleanup for variables using regular expressions.
Switched to manual parsing of template variables as regular expressions can contain { and } characters which makes matching variables using these as delimiters impossible.
Related ticket: #1414.
This commit is contained in:
@@ -24,7 +24,6 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.springframework.http.HttpMethod;
|
||||
@@ -42,7 +41,6 @@ import org.springframework.web.bind.annotation.RequestMethod;
|
||||
public class AnnotationMappingDiscoverer implements MappingDiscoverer {
|
||||
|
||||
private static final Pattern MULTIPLE_SLASHES = Pattern.compile("/{2,}");
|
||||
private static final Pattern TEMPLATE_VARIABLE_NAME = Pattern.compile("\\{(.*)\\}");
|
||||
|
||||
private final Class<? extends Annotation> annotationType;
|
||||
private final String mappingAttributeName;
|
||||
@@ -205,23 +203,44 @@ public class AnnotationMappingDiscoverer implements MappingDiscoverer {
|
||||
return MULTIPLE_SLASHES.matcher(result.toString()).replaceAll("/");
|
||||
}
|
||||
|
||||
private static String cleanupPart(String variable) {
|
||||
private static String cleanupPart(String part) {
|
||||
|
||||
if (!variable.contains("{")) {
|
||||
return variable;
|
||||
StringBuilder builder = new StringBuilder();
|
||||
int level = 0;
|
||||
boolean inRegex = false;
|
||||
|
||||
for (int i = 0; i < part.length(); i++) {
|
||||
|
||||
char character = part.charAt(i);
|
||||
|
||||
if (character == '{') {
|
||||
|
||||
level++;
|
||||
|
||||
if (level == 1) {
|
||||
builder.append(character);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (level == 1 && character == ':') {
|
||||
inRegex = true;
|
||||
}
|
||||
|
||||
if (character == '}') {
|
||||
|
||||
level--;
|
||||
|
||||
if (level == 0) {
|
||||
inRegex = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!inRegex) {
|
||||
builder.append(character);
|
||||
}
|
||||
}
|
||||
|
||||
Matcher matcher = TEMPLATE_VARIABLE_NAME.matcher(variable);
|
||||
|
||||
if (!matcher.find()) {
|
||||
return variable;
|
||||
}
|
||||
|
||||
String rawName = matcher.group(1);
|
||||
int colonIndex = rawName.indexOf(':');
|
||||
|
||||
return colonIndex < 0
|
||||
? variable
|
||||
: variable.replace(matcher.group(0), "{" + rawName.substring(0, colonIndex) + "}");
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,6 +160,14 @@ class AnnotationMappingDiscovererUnitTest {
|
||||
assertThat(discoverer.getMapping(method)).isEqualTo("/type/foo/{bar}");
|
||||
}
|
||||
|
||||
@Test // #1455
|
||||
void extractsMultipleRegularExpressionVariablesCorrectly() throws Exception {
|
||||
|
||||
Method method = MyController.class.getMethod("multipleRegularExpressions");
|
||||
|
||||
assertThat(discoverer.getMapping(method)).isEqualTo("/type/spring-web/{symbolicName}-{version}{extension}");
|
||||
}
|
||||
|
||||
@RequestMapping("/type")
|
||||
interface MyController {
|
||||
|
||||
@@ -174,6 +182,9 @@ class AnnotationMappingDiscovererUnitTest {
|
||||
|
||||
@RequestMapping("/foo/{bar:[ABC]{1}}")
|
||||
void mappingWithMatchingExpression();
|
||||
|
||||
@GetMapping("/spring-web/{symbolicName:[a-z-]+}-{version:\\d\\.\\d\\.\\d}{extension:\\.[a-z]+}")
|
||||
void multipleRegularExpressions();
|
||||
}
|
||||
|
||||
interface ControllerWithoutTypeLevelMapping {
|
||||
|
||||
Reference in New Issue
Block a user