Skip to content

Commit e994693

Browse files
committed
Remove Spring MVC suffixPattern and trailingSlash matching
See gh-34036
1 parent ca90948 commit e994693

File tree

20 files changed

+31
-960
lines changed

20 files changed

+31
-960
lines changed

spring-test/src/main/java/org/springframework/test/web/servlet/client/MockMvcWebTestClient.java

-10
Original file line numberDiff line numberDiff line change
@@ -370,16 +370,6 @@ ControllerSpec mappedInterceptors(
370370
*/
371371
ControllerSpec patternParser(PathPatternParser parser);
372372

373-
/**
374-
* Whether to match trailing slashes.
375-
* <p>This is delegated to
376-
* {@link StandaloneMockMvcBuilder#setUseTrailingSlashPatternMatch(boolean)}.
377-
* @deprecated as of 6.0, see
378-
* {@link PathPatternParser#setMatchOptionalTrailingSeparator(boolean)}
379-
*/
380-
@Deprecated(since = "6.0")
381-
ControllerSpec useTrailingSlashPatternMatch(boolean useTrailingSlashPatternMatch);
382-
383373
/**
384374
* Configure placeholder values to use.
385375
* <p>This is delegated to

spring-test/src/main/java/org/springframework/test/web/servlet/client/StandaloneMockMvcSpec.java

+1-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -152,13 +152,6 @@ public StandaloneMockMvcSpec patternParser(PathPatternParser parser) {
152152
return this;
153153
}
154154

155-
@SuppressWarnings("deprecation")
156-
@Override
157-
public StandaloneMockMvcSpec useTrailingSlashPatternMatch(boolean useTrailingSlashPatternMatch) {
158-
this.mockMvcBuilder.setUseTrailingSlashPatternMatch(useTrailingSlashPatternMatch);
159-
return this;
160-
}
161-
162155
@Override
163156
public StandaloneMockMvcSpec placeholderValue(String name, String value) {
164157
this.mockMvcBuilder.addPlaceholderValue(name, value);

spring-test/src/main/java/org/springframework/test/web/servlet/setup/StandaloneMockMvcBuilder.java

-34
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,6 @@ public class StandaloneMockMvcBuilder extends AbstractMockMvcBuilder<StandaloneM
130130
@Nullable
131131
private PathPatternParser patternParser;
132132

133-
private boolean useSuffixPatternMatch = false;
134-
135-
private boolean useTrailingSlashPatternMatch = false;
136-
137133
@Nullable
138134
private Boolean removeSemicolonContent;
139135

@@ -323,33 +319,6 @@ public StandaloneMockMvcBuilder setPatternParser(@Nullable PathPatternParser par
323319
return this;
324320
}
325321

326-
/**
327-
* Whether to use suffix pattern match (".*") when matching patterns to
328-
* requests. If enabled a method mapped to "/users" also matches to "/users.*".
329-
* <p>The default value is {@code false}.
330-
* @deprecated as of 5.2.4. See class-level note in
331-
* {@link RequestMappingHandlerMapping} on the deprecation of path extension
332-
* config options.
333-
*/
334-
@Deprecated
335-
public StandaloneMockMvcBuilder setUseSuffixPatternMatch(boolean useSuffixPatternMatch) {
336-
this.useSuffixPatternMatch = useSuffixPatternMatch;
337-
this.preferPathMatcher |= useSuffixPatternMatch;
338-
return this;
339-
}
340-
341-
/**
342-
* Whether to match to URLs irrespective of the presence of a trailing slash.
343-
* If enabled a method mapped to "/users" also matches to "/users/".
344-
* @deprecated as of 6.0, see
345-
* {@link PathPatternParser#setMatchOptionalTrailingSeparator(boolean)}
346-
*/
347-
@Deprecated(since = "6.0")
348-
public StandaloneMockMvcBuilder setUseTrailingSlashPatternMatch(boolean useTrailingSlashPatternMatch) {
349-
this.useTrailingSlashPatternMatch = useTrailingSlashPatternMatch;
350-
return this;
351-
}
352-
353322
/**
354323
* Set if ";" (semicolon) content should be stripped from the request URI. The value,
355324
* if provided, is in turn set on
@@ -469,7 +438,6 @@ protected Map<String, Object> extendMvcSingletons(@Nullable ServletContext servl
469438
/** Using the MVC Java configuration as the starting point for the "standalone" setup. */
470439
private class StandaloneConfiguration extends WebMvcConfigurationSupport {
471440

472-
@SuppressWarnings("deprecation")
473441
public RequestMappingHandlerMapping getHandlerMapping(
474442
FormattingConversionService mvcConversionService,
475443
ResourceUrlProvider mvcResourceUrlProvider) {
@@ -478,7 +446,6 @@ public RequestMappingHandlerMapping getHandlerMapping(
478446
handlerMapping.setEmbeddedValueResolver(new StaticStringValueResolver(placeholderValues));
479447
if (patternParser == null && preferPathMatcher) {
480448
handlerMapping.setPatternParser(null);
481-
handlerMapping.setUseSuffixPatternMatch(useSuffixPatternMatch);
482449
if (removeSemicolonContent != null) {
483450
UrlPathHelper pathHelper = new UrlPathHelper();
484451
pathHelper.setRemoveSemicolonContent(removeSemicolonContent);
@@ -488,7 +455,6 @@ public RequestMappingHandlerMapping getHandlerMapping(
488455
else if (patternParser != null) {
489456
handlerMapping.setPatternParser(patternParser);
490457
}
491-
handlerMapping.setUseTrailingSlashMatch(useTrailingSlashPatternMatch);
492458
handlerMapping.setOrder(0);
493459
handlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));
494460
return handlerMapping;

spring-test/src/test/java/org/springframework/test/web/servlet/setup/StandaloneMockMvcBuilderTests.java

-19
Original file line numberDiff line numberDiff line change
@@ -74,25 +74,6 @@ void placeHoldersInRequestMapping() throws Exception {
7474
assertThat(((HandlerMethod) chain.getHandler()).getMethod().getName()).isEqualTo("handleWithPlaceholders");
7575
}
7676

77-
@Test // SPR-13637
78-
@SuppressWarnings("deprecation")
79-
void suffixPatternMatch() throws Exception {
80-
TestStandaloneMockMvcBuilder builder = new TestStandaloneMockMvcBuilder(new PersonController());
81-
builder.setUseSuffixPatternMatch(false);
82-
builder.build();
83-
84-
RequestMappingHandlerMapping hm = builder.wac.getBean(RequestMappingHandlerMapping.class);
85-
86-
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/persons");
87-
HandlerExecutionChain chain = hm.getHandler(request);
88-
assertThat(chain).isNotNull();
89-
assertThat(((HandlerMethod) chain.getHandler()).getMethod().getName()).isEqualTo("persons");
90-
91-
request = new MockHttpServletRequest("GET", "/persons.xml");
92-
chain = hm.getHandler(request);
93-
assertThat(chain).isNull();
94-
}
95-
9677
@Test // SPR-12553
9778
void applicationContextAttribute() {
9879
TestStandaloneMockMvcBuilder builder = new TestStandaloneMockMvcBuilder(new PlaceholderController());

spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java

-14
Original file line numberDiff line numberDiff line change
@@ -409,21 +409,7 @@ private void configurePathMatchingProperties(
409409
Element pathMatchingElement = DomUtils.getChildElementByTagName(element, "path-matching");
410410
Object source = context.extractSource(element);
411411
if (pathMatchingElement != null) {
412-
if (pathMatchingElement.hasAttribute("trailing-slash")) {
413-
boolean useTrailingSlashMatch = Boolean.parseBoolean(pathMatchingElement.getAttribute("trailing-slash"));
414-
handlerMappingDef.getPropertyValues().add("useTrailingSlashMatch", useTrailingSlashMatch);
415-
}
416412
boolean preferPathMatcher = false;
417-
if (pathMatchingElement.hasAttribute("suffix-pattern")) {
418-
boolean useSuffixPatternMatch = Boolean.parseBoolean(pathMatchingElement.getAttribute("suffix-pattern"));
419-
handlerMappingDef.getPropertyValues().add("useSuffixPatternMatch", useSuffixPatternMatch);
420-
preferPathMatcher |= useSuffixPatternMatch;
421-
}
422-
if (pathMatchingElement.hasAttribute("registered-suffixes-only")) {
423-
boolean useRegisteredSuffixPatternMatch = Boolean.parseBoolean(pathMatchingElement.getAttribute("registered-suffixes-only"));
424-
handlerMappingDef.getPropertyValues().add("useRegisteredSuffixPatternMatch", useRegisteredSuffixPatternMatch);
425-
preferPathMatcher |= useRegisteredSuffixPatternMatch;
426-
}
427413

428414
RuntimeBeanReference pathHelperRef = null;
429415
if (pathMatchingElement.hasAttribute("path-helper")) {

spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/PathMatchConfigurer.java

+1-98
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -23,7 +23,6 @@
2323
import org.springframework.lang.Nullable;
2424
import org.springframework.util.AntPathMatcher;
2525
import org.springframework.util.PathMatcher;
26-
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
2726
import org.springframework.web.util.UrlPathHelper;
2827
import org.springframework.web.util.pattern.PathPattern;
2928
import org.springframework.web.util.pattern.PathPatternParser;
@@ -49,18 +48,9 @@ public class PathMatchConfigurer {
4948
@Nullable
5049
private PathPatternParser patternParser;
5150

52-
@Nullable
53-
private Boolean trailingSlashMatch;
54-
5551
@Nullable
5652
private Map<String, Predicate<Class<?>>> pathPrefixes;
5753

58-
@Nullable
59-
private Boolean suffixPatternMatch;
60-
61-
@Nullable
62-
private Boolean registeredSuffixPatternMatch;
63-
6454
@Nullable
6555
private UrlPathHelper urlPathHelper;
6656

@@ -84,8 +74,6 @@ public class PathMatchConfigurer {
8474
* <p><strong>Note:</strong> This property is mutually exclusive with the
8575
* following other, {@code AntPathMatcher} related properties:
8676
* <ul>
87-
* <li>{@link #setUseSuffixPatternMatch(Boolean)}
88-
* <li>{@link #setUseRegisteredSuffixPatternMatch(Boolean)}
8977
* <li>{@link #setUrlPathHelper(UrlPathHelper)}
9078
* <li>{@link #setPathMatcher(PathMatcher)}
9179
* </ul>
@@ -103,20 +91,6 @@ public PathMatchConfigurer setPatternParser(@Nullable PathPatternParser patternP
10391
return this;
10492
}
10593

106-
/**
107-
* Whether to match to URLs irrespective of the presence of a trailing slash.
108-
* If enabled a method mapped to "/users" also matches to "/users/".
109-
* <p>The default was changed in 6.0 from {@code true} to {@code false} in
110-
* order to support the deprecation of the property.
111-
* @deprecated as of 6.0, see
112-
* {@link PathPatternParser#setMatchOptionalTrailingSeparator(boolean)}
113-
*/
114-
@Deprecated(since = "6.0")
115-
public PathMatchConfigurer setUseTrailingSlashMatch(Boolean trailingSlashMatch) {
116-
this.trailingSlashMatch = trailingSlashMatch;
117-
return this;
118-
}
119-
12094
/**
12195
* Configure a path prefix to apply to matching controller methods.
12296
* <p>Prefixes are used to enrich the mappings of every {@code @RequestMapping}
@@ -136,49 +110,6 @@ public PathMatchConfigurer addPathPrefix(String prefix, Predicate<Class<?>> pred
136110
return this;
137111
}
138112

139-
/**
140-
* Whether to use suffix pattern match (".*") when matching patterns to
141-
* requests. If enabled a method mapped to "/users" also matches to "/users.*".
142-
* <p><strong>Note:</strong> This property is mutually exclusive with
143-
* {@link #setPatternParser(PathPatternParser)}. If set, it enables use of
144-
* String path matching, unless a {@code PathPatternParser} is also
145-
* explicitly set in which case this property is ignored.
146-
* <p>By default this is set to {@code false}.
147-
* @deprecated as of 5.2.4. See class-level note in
148-
* {@link RequestMappingHandlerMapping} on the deprecation of path extension
149-
* config options. As there is no replacement for this method, in 5.2.x it is
150-
* necessary to set it to {@code false}. In 5.3 the default changes to
151-
* {@code false} and use of this property becomes unnecessary.
152-
*/
153-
@Deprecated
154-
public PathMatchConfigurer setUseSuffixPatternMatch(@Nullable Boolean suffixPatternMatch) {
155-
this.suffixPatternMatch = suffixPatternMatch;
156-
this.preferPathMatcher |= (suffixPatternMatch != null && suffixPatternMatch);
157-
return this;
158-
}
159-
160-
/**
161-
* Whether suffix pattern matching should work only against path extensions
162-
* explicitly registered when you
163-
* {@link WebMvcConfigurer#configureContentNegotiation configure content
164-
* negotiation}. This is generally recommended to reduce ambiguity and to
165-
* avoid issues such as when a "." appears in the path for other reasons.
166-
* <p><strong>Note:</strong> This property is mutually exclusive with
167-
* {@link #setPatternParser(PathPatternParser)}. If set, it enables use of
168-
* String path matching, unless a {@code PathPatternParser} is also
169-
* explicitly set in which case this property is ignored.
170-
* <p>By default this is set to "false".
171-
* @deprecated as of 5.2.4. See class-level note in
172-
* {@link RequestMappingHandlerMapping} on the deprecation of path extension
173-
* config options.
174-
*/
175-
@Deprecated
176-
public PathMatchConfigurer setUseRegisteredSuffixPatternMatch(@Nullable Boolean registeredSuffixPatternMatch) {
177-
this.registeredSuffixPatternMatch = registeredSuffixPatternMatch;
178-
this.preferPathMatcher |= (registeredSuffixPatternMatch != null && registeredSuffixPatternMatch);
179-
return this;
180-
}
181-
182113
/**
183114
* Set the UrlPathHelper to use to resolve the mapping path for the application.
184115
* <p><strong>Note:</strong> This property is mutually exclusive with
@@ -232,39 +163,11 @@ public PathPatternParser getPatternParser() {
232163
return this.patternParser;
233164
}
234165

235-
@Nullable
236-
@Deprecated
237-
public Boolean isUseTrailingSlashMatch() {
238-
return this.trailingSlashMatch;
239-
}
240-
241166
@Nullable
242167
protected Map<String, Predicate<Class<?>>> getPathPrefixes() {
243168
return this.pathPrefixes;
244169
}
245170

246-
/**
247-
* Whether to use registered suffixes for pattern matching.
248-
* @deprecated as of 5.2.4, see deprecation note on
249-
* {@link #setUseRegisteredSuffixPatternMatch(Boolean)}.
250-
*/
251-
@Nullable
252-
@Deprecated
253-
public Boolean isUseRegisteredSuffixPatternMatch() {
254-
return this.registeredSuffixPatternMatch;
255-
}
256-
257-
/**
258-
* Whether to use registered suffixes for pattern matching.
259-
* @deprecated as of 5.2.4, see deprecation note on
260-
* {@link #setUseSuffixPatternMatch(Boolean)}.
261-
*/
262-
@Nullable
263-
@Deprecated
264-
public Boolean isUseSuffixPatternMatch() {
265-
return this.suffixPatternMatch;
266-
}
267-
268171
@Nullable
269172
public UrlPathHelper getUrlPathHelper() {
270173
return this.urlPathHelper;

spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java

+2-16
Original file line numberDiff line numberDiff line change
@@ -321,22 +321,6 @@ public RequestMappingHandlerMapping requestMappingHandlerMapping(
321321
initHandlerMapping(mapping, conversionService, resourceUrlProvider);
322322

323323
PathMatchConfigurer pathConfig = getPathMatchConfigurer();
324-
if (pathConfig.preferPathMatcher()) {
325-
Boolean useSuffixPatternMatch = pathConfig.isUseSuffixPatternMatch();
326-
if (useSuffixPatternMatch != null) {
327-
mapping.setUseSuffixPatternMatch(useSuffixPatternMatch);
328-
}
329-
Boolean useRegisteredSuffixPatternMatch = pathConfig.isUseRegisteredSuffixPatternMatch();
330-
if (useRegisteredSuffixPatternMatch != null) {
331-
mapping.setUseRegisteredSuffixPatternMatch(useRegisteredSuffixPatternMatch);
332-
}
333-
}
334-
335-
Boolean useTrailingSlashMatch = pathConfig.isUseTrailingSlashMatch();
336-
if (useTrailingSlashMatch != null) {
337-
mapping.setUseTrailingSlashMatch(useTrailingSlashMatch);
338-
}
339-
340324
if (pathConfig.getPathPrefixes() != null) {
341325
mapping.setPathPrefixes(pathConfig.getPathPrefixes());
342326
}
@@ -520,6 +504,8 @@ private void initHandlerMapping(
520504
else if (pathConfig.getPatternParser() != null) {
521505
mapping.setPatternParser(pathConfig.getPatternParser());
522506
}
507+
// else: AbstractHandlerMapping defaults to PathPatternParser
508+
523509
mapping.setInterceptors(getInterceptors(conversionService, resourceUrlProvider));
524510
mapping.setCorsConfigurations(getCorsConfigurations());
525511
}

0 commit comments

Comments
 (0)