Remove remaining Spring MVC trailing slash matching
Closes gh-34036
This commit is contained in:
parent
2e6046a655
commit
4b9f1732f1
|
@ -118,12 +118,12 @@ See the sections on xref:web/webmvc-cors.adoc[CORS] and the xref:web/webmvc-cors
|
||||||
[.small]#xref:web/webflux/reactive-spring.adoc#filters.url-handler[See equivalent in the Reactive stack]#
|
[.small]#xref:web/webflux/reactive-spring.adoc#filters.url-handler[See equivalent in the Reactive stack]#
|
||||||
|
|
||||||
In previous Spring Framework versions, Spring MVC could be configured to ignore trailing slashes in URL paths
|
In previous Spring Framework versions, Spring MVC could be configured to ignore trailing slashes in URL paths
|
||||||
when mapping incoming requests on controller methods. This could be done by enabling the `setUseTrailingSlashMatch`
|
when mapping incoming requests on controller methods. This means that sending a "GET /home/" request would be
|
||||||
option on the `PathMatchConfigurer`. This means that sending a "GET /home/" request would be handled by a controller
|
handled by a controller method annotated with `@GetMapping("/home")`.
|
||||||
method annotated with `@GetMapping("/home")`.
|
|
||||||
|
|
||||||
This option has been retired, but applications are still expected to handle such requests in a safe way.
|
This option was deprecated in 6.0 and removed in 7.0, but applications are still expected to handle such
|
||||||
The `UrlHandlerFilter` Servlet filter has been designed for this purpose. It can be configured to:
|
requests in a safe way. The `UrlHandlerFilter` Servlet filter has been designed for this purpose.
|
||||||
|
It can be configured to:
|
||||||
|
|
||||||
* respond with an HTTP redirect status when receiving URLs with trailing slashes, sending browsers to the non-trailing slash URL variant.
|
* respond with an HTTP redirect status when receiving URLs with trailing slashes, sending browsers to the non-trailing slash URL variant.
|
||||||
* wrap the request to act as if the request was sent without a trailing slash and continue the processing of the request.
|
* wrap the request to act as if the request was sent without a trailing slash and continue the processing of the request.
|
||||||
|
|
|
@ -66,8 +66,6 @@ public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping i
|
||||||
@Nullable
|
@Nullable
|
||||||
private Object rootHandler;
|
private Object rootHandler;
|
||||||
|
|
||||||
private boolean useTrailingSlashMatch = false;
|
|
||||||
|
|
||||||
private boolean lazyInitHandlers = false;
|
private boolean lazyInitHandlers = false;
|
||||||
|
|
||||||
private final Map<String, Object> handlerMap = new LinkedHashMap<>();
|
private final Map<String, Object> handlerMap = new LinkedHashMap<>();
|
||||||
|
@ -101,28 +99,6 @@ public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping i
|
||||||
return this.rootHandler;
|
return this.rootHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether to match to URLs irrespective of the presence of a trailing slash.
|
|
||||||
* If enabled a URL pattern such as "/users" also matches to "/users/".
|
|
||||||
* <p>The default value is {@code false}.
|
|
||||||
* @deprecated as of 6.0, see
|
|
||||||
* {@link PathPatternParser#setMatchOptionalTrailingSeparator(boolean)}
|
|
||||||
*/
|
|
||||||
@Deprecated(since = "6.0")
|
|
||||||
public void setUseTrailingSlashMatch(boolean useTrailingSlashMatch) {
|
|
||||||
this.useTrailingSlashMatch = useTrailingSlashMatch;
|
|
||||||
if (getPatternParser() != null) {
|
|
||||||
getPatternParser().setMatchOptionalTrailingSeparator(useTrailingSlashMatch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether to match to URLs irrespective of the presence of a trailing slash.
|
|
||||||
*/
|
|
||||||
public boolean useTrailingSlashMatch() {
|
|
||||||
return this.useTrailingSlashMatch;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set whether to lazily initialize handlers. Only applicable to
|
* Set whether to lazily initialize handlers. Only applicable to
|
||||||
* singleton handlers, as prototypes are always lazily initialized.
|
* singleton handlers, as prototypes are always lazily initialized.
|
||||||
|
@ -360,11 +336,6 @@ public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping i
|
||||||
if (getPathMatcher().match(registeredPattern, lookupPath)) {
|
if (getPathMatcher().match(registeredPattern, lookupPath)) {
|
||||||
matchingPatterns.add(registeredPattern);
|
matchingPatterns.add(registeredPattern);
|
||||||
}
|
}
|
||||||
else if (useTrailingSlashMatch()) {
|
|
||||||
if (!registeredPattern.endsWith("/") && getPathMatcher().match(registeredPattern + "/", lookupPath)) {
|
|
||||||
matchingPatterns.add(registeredPattern + "/");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String bestMatch = null;
|
String bestMatch = null;
|
||||||
|
@ -495,11 +466,6 @@ public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping i
|
||||||
if (getPathMatcher().match(pattern, lookupPath)) {
|
if (getPathMatcher().match(pattern, lookupPath)) {
|
||||||
return new RequestMatchResult(pattern, lookupPath, getPathMatcher());
|
return new RequestMatchResult(pattern, lookupPath, getPathMatcher());
|
||||||
}
|
}
|
||||||
else if (useTrailingSlashMatch()) {
|
|
||||||
if (!pattern.endsWith("/") && getPathMatcher().match(pattern + "/", lookupPath)) {
|
|
||||||
return new RequestMatchResult(pattern + "/", lookupPath, getPathMatcher());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,29 +126,6 @@ class PathPatternsRequestConditionTests {
|
||||||
assertThat(match).isEqualTo(expected);
|
assertThat(match).isEqualTo(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
void matchTrailingSlash() {
|
|
||||||
MockHttpServletRequest request = createRequest("/foo/");
|
|
||||||
|
|
||||||
PathPatternParser patternParser = new PathPatternParser();
|
|
||||||
patternParser.setMatchOptionalTrailingSeparator(true);
|
|
||||||
|
|
||||||
PathPatternsRequestCondition condition = new PathPatternsRequestCondition(patternParser, "/foo");
|
|
||||||
PathPatternsRequestCondition match = condition.getMatchingCondition(request);
|
|
||||||
|
|
||||||
assertThat(match).isNotNull();
|
|
||||||
assertThat(match.getPatternValues()).containsExactly("/foo");
|
|
||||||
|
|
||||||
PathPatternParser strictParser = new PathPatternParser();
|
|
||||||
strictParser.setMatchOptionalTrailingSeparator(false);
|
|
||||||
|
|
||||||
condition = new PathPatternsRequestCondition(strictParser, "/foo");
|
|
||||||
match = condition.getMatchingCondition(request);
|
|
||||||
|
|
||||||
assertThat(match).isNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void matchPatternContainsExtension() {
|
void matchPatternContainsExtension() {
|
||||||
MockHttpServletRequest request = createRequest("/foo.html");
|
MockHttpServletRequest request = createRequest("/foo.html");
|
||||||
|
|
Loading…
Reference in New Issue