SPR-6164 Add option to disable '.*' pattern matching in RequestMappingHandlerMapping and PatternsRequestCondition
This commit is contained in:
parent
2b5d2e5a0a
commit
8292491a53
|
|
@ -44,7 +44,7 @@ import org.springframework.web.servlet.mvc.condition.HeadersRequestCondition.Hea
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
public class ConsumesRequestCondition extends AbstractRequestCondition<ConsumesRequestCondition> {
|
public final class ConsumesRequestCondition extends AbstractRequestCondition<ConsumesRequestCondition> {
|
||||||
|
|
||||||
private final List<ConsumeMediaTypeExpression> expressions;
|
private final List<ConsumeMediaTypeExpression> expressions;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
public class HeadersRequestCondition extends AbstractRequestCondition<HeadersRequestCondition> {
|
public final class HeadersRequestCondition extends AbstractRequestCondition<HeadersRequestCondition> {
|
||||||
|
|
||||||
private final Set<HeaderExpression> expressions;
|
private final Set<HeaderExpression> expressions;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ import org.springframework.web.util.WebUtils;
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
public class ParamsRequestCondition extends AbstractRequestCondition<ParamsRequestCondition> {
|
public final class ParamsRequestCondition extends AbstractRequestCondition<ParamsRequestCondition> {
|
||||||
|
|
||||||
private final Set<ParamExpression> expressions;
|
private final Set<ParamExpression> expressions;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ import org.springframework.web.util.UrlPathHelper;
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
public class PatternsRequestCondition extends AbstractRequestCondition<PatternsRequestCondition> {
|
public final class PatternsRequestCondition extends AbstractRequestCondition<PatternsRequestCondition> {
|
||||||
|
|
||||||
private final Set<String> patterns;
|
private final Set<String> patterns;
|
||||||
|
|
||||||
|
|
@ -49,14 +49,7 @@ public class PatternsRequestCondition extends AbstractRequestCondition<PatternsR
|
||||||
|
|
||||||
private final PathMatcher pathMatcher;
|
private final PathMatcher pathMatcher;
|
||||||
|
|
||||||
/**
|
private final boolean useSuffixPatternMatch;
|
||||||
* Creates a new {@link PatternsRequestCondition} with the given URL patterns.
|
|
||||||
* Each pattern that is not empty and does not start with "/" is prepended with "/".
|
|
||||||
* @param patterns 0 or more URL patterns; if 0 the condition will match to every request.
|
|
||||||
*/
|
|
||||||
public PatternsRequestCondition(String... patterns) {
|
|
||||||
this(patterns, new UrlPathHelper(), new AntPathMatcher());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@link PatternsRequestCondition} with the given URL patterns.
|
* Creates a new {@link PatternsRequestCondition} with the given URL patterns.
|
||||||
|
|
@ -65,9 +58,22 @@ public class PatternsRequestCondition extends AbstractRequestCondition<PatternsR
|
||||||
* @param patterns the URL patterns to use; if 0, the condition will match to every request.
|
* @param patterns the URL patterns to use; if 0, the condition will match to every request.
|
||||||
* @param urlPathHelper a {@link UrlPathHelper} for determining the lookup path for a request
|
* @param urlPathHelper a {@link UrlPathHelper} for determining the lookup path for a request
|
||||||
* @param pathMatcher a {@link PathMatcher} for pattern path matching
|
* @param pathMatcher a {@link PathMatcher} for pattern path matching
|
||||||
|
* @param useSuffixPatternMatch whether to enable matching by suffix (".*")
|
||||||
*/
|
*/
|
||||||
public PatternsRequestCondition(String[] patterns, UrlPathHelper urlPathHelper, PathMatcher pathMatcher) {
|
public PatternsRequestCondition(String[] patterns,
|
||||||
this(asList(patterns), urlPathHelper, pathMatcher);
|
UrlPathHelper urlPathHelper,
|
||||||
|
PathMatcher pathMatcher,
|
||||||
|
boolean useSuffixPatternMatch) {
|
||||||
|
this(asList(patterns), urlPathHelper, pathMatcher, useSuffixPatternMatch);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new {@link PatternsRequestCondition} with the given URL patterns.
|
||||||
|
* Each pattern that is not empty and does not start with "/" is prepended with "/".
|
||||||
|
* @param patterns 0 or more URL patterns; if 0 the condition will match to every request.
|
||||||
|
*/
|
||||||
|
public PatternsRequestCondition(String... patterns) {
|
||||||
|
this(patterns, null, null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<String> asList(String... patterns) {
|
private static List<String> asList(String... patterns) {
|
||||||
|
|
@ -77,10 +83,14 @@ public class PatternsRequestCondition extends AbstractRequestCondition<PatternsR
|
||||||
/**
|
/**
|
||||||
* Private constructor.
|
* Private constructor.
|
||||||
*/
|
*/
|
||||||
private PatternsRequestCondition(Collection<String> patterns, UrlPathHelper urlPathHelper, PathMatcher pathMatcher) {
|
private PatternsRequestCondition(Collection<String> patterns,
|
||||||
|
UrlPathHelper urlPathHelper,
|
||||||
|
PathMatcher pathMatcher,
|
||||||
|
boolean useSuffixPatternMatch) {
|
||||||
this.patterns = Collections.unmodifiableSet(prependLeadingSlash(patterns));
|
this.patterns = Collections.unmodifiableSet(prependLeadingSlash(patterns));
|
||||||
this.urlPathHelper = urlPathHelper;
|
this.urlPathHelper = urlPathHelper != null ? urlPathHelper : new UrlPathHelper();
|
||||||
this.pathMatcher = pathMatcher;
|
this.pathMatcher = pathMatcher != null ? pathMatcher : new AntPathMatcher();
|
||||||
|
this.useSuffixPatternMatch = useSuffixPatternMatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Set<String> prependLeadingSlash(Collection<String> patterns) {
|
private static Set<String> prependLeadingSlash(Collection<String> patterns) {
|
||||||
|
|
@ -139,7 +149,7 @@ public class PatternsRequestCondition extends AbstractRequestCondition<PatternsR
|
||||||
else {
|
else {
|
||||||
result.add("");
|
result.add("");
|
||||||
}
|
}
|
||||||
return new PatternsRequestCondition(result, urlPathHelper, pathMatcher);
|
return new PatternsRequestCondition(result, urlPathHelper, pathMatcher, useSuffixPatternMatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -172,17 +182,20 @@ public class PatternsRequestCondition extends AbstractRequestCondition<PatternsR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Collections.sort(matches, pathMatcher.getPatternComparator(lookupPath));
|
Collections.sort(matches, pathMatcher.getPatternComparator(lookupPath));
|
||||||
return matches.isEmpty() ? null : new PatternsRequestCondition(matches, urlPathHelper, pathMatcher);
|
return matches.isEmpty() ? null :
|
||||||
|
new PatternsRequestCondition(matches, urlPathHelper, pathMatcher, useSuffixPatternMatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getMatchingPattern(String pattern, String lookupPath) {
|
private String getMatchingPattern(String pattern, String lookupPath) {
|
||||||
if (pattern.equals(lookupPath)) {
|
if (pattern.equals(lookupPath)) {
|
||||||
return pattern;
|
return pattern;
|
||||||
}
|
}
|
||||||
|
if (useSuffixPatternMatch) {
|
||||||
boolean hasSuffix = pattern.indexOf('.') != -1;
|
boolean hasSuffix = pattern.indexOf('.') != -1;
|
||||||
if (!hasSuffix && pathMatcher.match(pattern + ".*", lookupPath)) {
|
if (!hasSuffix && pathMatcher.match(pattern + ".*", lookupPath)) {
|
||||||
return pattern + ".*";
|
return pattern + ".*";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (pathMatcher.match(pattern, lookupPath)) {
|
if (pathMatcher.match(pattern, lookupPath)) {
|
||||||
return pattern;
|
return pattern;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ import org.springframework.web.servlet.mvc.condition.HeadersRequestCondition.Hea
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
public class ProducesRequestCondition extends AbstractRequestCondition<ProducesRequestCondition> {
|
public final class ProducesRequestCondition extends AbstractRequestCondition<ProducesRequestCondition> {
|
||||||
|
|
||||||
private final List<ProduceMediaTypeExpression> expressions;
|
private final List<ProduceMediaTypeExpression> expressions;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
public class RequestMethodsRequestCondition extends AbstractRequestCondition<RequestMethodsRequestCondition> {
|
public final class RequestMethodsRequestCondition extends AbstractRequestCondition<RequestMethodsRequestCondition> {
|
||||||
|
|
||||||
private final Set<RequestMethod> methods;
|
private final Set<RequestMethod> methods;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ import org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondit
|
||||||
* <li>{@link ProducesRequestCondition}</li>
|
* <li>{@link ProducesRequestCondition}</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* Optionally a custom request condition may also be provided.
|
* Optionally a custom request condition may be provided.
|
||||||
*
|
*
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
|
|
@ -80,6 +80,14 @@ public final class RequestMappingInfo {
|
||||||
this.customCondition = custom != null ? new CustomRequestCondition(custom) : new CustomRequestCondition();
|
this.customCondition = custom != null ? new CustomRequestCondition(custom) : new CustomRequestCondition();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-create a {@link RequestMappingInfo} with the given custom {@link RequestCondition}.
|
||||||
|
*/
|
||||||
|
public RequestMappingInfo(RequestMappingInfo info, RequestCondition<?> customRequestCondition) {
|
||||||
|
this(info.patternsCondition, info.methodsCondition, info.paramsCondition, info.headersCondition,
|
||||||
|
info.consumesCondition, info.producesCondition, customRequestCondition);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the URL patterns of this {@link RequestMappingInfo};
|
* Returns the URL patterns of this {@link RequestMappingInfo};
|
||||||
* or instance with 0 patterns, never {@code null}
|
* or instance with 0 patterns, never {@code null}
|
||||||
|
|
|
||||||
|
|
@ -20,13 +20,13 @@ import java.lang.reflect.Method;
|
||||||
|
|
||||||
import org.springframework.core.annotation.AnnotationUtils;
|
import org.springframework.core.annotation.AnnotationUtils;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.util.PathMatcher;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.servlet.mvc.condition.ConsumesRequestCondition;
|
import org.springframework.web.servlet.mvc.condition.ConsumesRequestCondition;
|
||||||
import org.springframework.web.servlet.mvc.condition.HeadersRequestCondition;
|
import org.springframework.web.servlet.mvc.condition.HeadersRequestCondition;
|
||||||
import org.springframework.web.servlet.mvc.condition.ParamsRequestCondition;
|
import org.springframework.web.servlet.mvc.condition.ParamsRequestCondition;
|
||||||
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
|
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
|
||||||
import org.springframework.web.servlet.mvc.condition.ProducesRequestCondition;
|
import org.springframework.web.servlet.mvc.condition.ProducesRequestCondition;
|
||||||
|
import org.springframework.web.servlet.mvc.condition.RequestCondition;
|
||||||
import org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondition;
|
import org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondition;
|
||||||
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
|
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
|
||||||
import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;
|
import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;
|
||||||
|
|
@ -41,9 +41,28 @@ import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMappi
|
||||||
*/
|
*/
|
||||||
public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMapping {
|
public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMapping {
|
||||||
|
|
||||||
|
private boolean useSuffixPatternMatch = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc} The handler determination in this method is made based on the presence of a type-level {@link
|
* Set whether to use a suffix pattern match (".*") when matching patterns to URLs.
|
||||||
* Controller} annotation.
|
* If enabled a method mapped to "/users" will also match to "/users.*".
|
||||||
|
* <p>Default is "true". Turn this convention off if you intend to interpret path mappings strictly.
|
||||||
|
*/
|
||||||
|
public void setUseSuffixPatternMatch(boolean useSuffixPatternMatch) {
|
||||||
|
this.useSuffixPatternMatch = useSuffixPatternMatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value of the useSuffixPatternMatch flag, see {@link #setUseSuffixPatternMatch(boolean)}.
|
||||||
|
*/
|
||||||
|
public boolean isUseSuffixPatternMatch() {
|
||||||
|
return useSuffixPatternMatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* The default implementation checks for the presence of a type-level {@link Controller}
|
||||||
|
* annotation via {@link AnnotationUtils#findAnnotation(Class, Class)}.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected boolean isHandler(Class<?> beanType) {
|
protected boolean isHandler(Class<?> beanType) {
|
||||||
|
|
@ -51,40 +70,54 @@ public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMappi
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a {@link RequestMappingInfo} for the given method. <p>Only {@link RequestMapping @RequestMapping}-annotated
|
* Determines if the given method is a handler method and creates a {@link RequestMappingInfo} for it.
|
||||||
* methods are considered. Type-level {@link RequestMapping @RequestMapping} annotations are also detected and their
|
|
||||||
* attributes combined with method-level {@link RequestMapping @RequestMapping} attributes.
|
|
||||||
*
|
*
|
||||||
* @param method the method to create a mapping for
|
* <p>The default implementation expects the presence of a method-level @{@link RequestMapping}
|
||||||
|
* annotation via {@link AnnotationUtils#findAnnotation(Class, Class)}. The presence of
|
||||||
|
* type-level annotations is also checked and if present a RequestMappingInfo is created for each type-
|
||||||
|
* and method-level annotations and combined via {@link RequestMappingInfo#combine(RequestMappingInfo)}.
|
||||||
|
*
|
||||||
|
* @param method the method to create a RequestMappingInfo for
|
||||||
* @param handlerType the actual handler type, possibly a sub-type of {@code method.getDeclaringClass()}
|
* @param handlerType the actual handler type, possibly a sub-type of {@code method.getDeclaringClass()}
|
||||||
* @return the mapping, or {@code null}
|
* @return the info, or {@code null}
|
||||||
* @see RequestMappingInfo#combine(RequestMappingInfo, PathMatcher)
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
|
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
|
||||||
RequestMapping methodAnnotation = AnnotationUtils.findAnnotation(method, RequestMapping.class);
|
RequestMapping methodAnnot = AnnotationUtils.findAnnotation(method, RequestMapping.class);
|
||||||
if (methodAnnotation == null) {
|
if (methodAnnot != null) {
|
||||||
return null;
|
RequestMapping typeAnnot = AnnotationUtils.findAnnotation(handlerType, RequestMapping.class);
|
||||||
}
|
RequestMappingInfo methodInfo = createRequestMappingInfo(methodAnnot, handlerType, method);
|
||||||
RequestMappingInfo methodInfo = createFromRequestMapping(methodAnnotation);
|
if (typeAnnot != null) {
|
||||||
RequestMapping typeAnnotation = AnnotationUtils.findAnnotation(handlerType, RequestMapping.class);
|
RequestMappingInfo typeInfo = createRequestMappingInfo(typeAnnot, handlerType, method);
|
||||||
if (typeAnnotation != null) {
|
|
||||||
RequestMappingInfo typeInfo = createFromRequestMapping(typeAnnotation);
|
|
||||||
return typeInfo.combine(methodInfo);
|
return typeInfo.combine(methodInfo);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return methodInfo;
|
return methodInfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private RequestMappingInfo createFromRequestMapping(RequestMapping annotation) {
|
/**
|
||||||
|
* Override this method to create a {@link RequestMappingInfo} from a @{@link RequestMapping} annotation. The main
|
||||||
|
* reason for doing so is to provide a custom {@link RequestCondition} to the RequestMappingInfo constructor.
|
||||||
|
*
|
||||||
|
* <p>This method is invoked both for type- and method-level @{@link RequestMapping} annotations. The resulting
|
||||||
|
* {@link RequestMappingInfo}s are combined via {@link RequestMappingInfo#combine(RequestMappingInfo)}.
|
||||||
|
*
|
||||||
|
* @param annot a type- or a method-level {@link RequestMapping} annotation
|
||||||
|
* @param handlerType the handler type
|
||||||
|
* @param method the method with which the created RequestMappingInfo will be combined
|
||||||
|
* @return a {@link RequestMappingInfo} instance; never {@code null}
|
||||||
|
*/
|
||||||
|
protected RequestMappingInfo createRequestMappingInfo(RequestMapping annot, Class<?> handlerType, Method method) {
|
||||||
return new RequestMappingInfo(
|
return new RequestMappingInfo(
|
||||||
new PatternsRequestCondition(annotation.value(), getUrlPathHelper(), getPathMatcher()),
|
new PatternsRequestCondition(annot.value(), getUrlPathHelper(), getPathMatcher(), useSuffixPatternMatch),
|
||||||
new RequestMethodsRequestCondition(annotation.method()),
|
new RequestMethodsRequestCondition(annot.method()),
|
||||||
new ParamsRequestCondition(annotation.params()),
|
new ParamsRequestCondition(annot.params()),
|
||||||
new HeadersRequestCondition(annotation.headers()),
|
new HeadersRequestCondition(annot.headers()),
|
||||||
new ConsumesRequestCondition(annotation.consumes(), annotation.headers()),
|
new ConsumesRequestCondition(annot.consumes(), annot.headers()),
|
||||||
new ProducesRequestCondition(annotation.produces(), annotation.headers()), null);
|
new ProducesRequestCondition(annot.produces(), annot.headers()), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -97,21 +97,39 @@ public class PatternsRequestConditionTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void matchImplicitByExtension() {
|
public void matchSuffixPattern() {
|
||||||
PatternsRequestCondition condition = new PatternsRequestCondition("/foo");
|
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo.html");
|
||||||
PatternsRequestCondition match = condition.getMatchingCondition(new MockHttpServletRequest("GET", "/foo.html"));
|
|
||||||
|
PatternsRequestCondition condition = new PatternsRequestCondition("/{foo}");
|
||||||
|
PatternsRequestCondition match = condition.getMatchingCondition(request);
|
||||||
|
|
||||||
assertNotNull(match);
|
assertNotNull(match);
|
||||||
assertEquals("/foo.*", match.getPatterns().iterator().next());
|
assertEquals("/{foo}.*", match.getPatterns().iterator().next());
|
||||||
|
|
||||||
|
condition = new PatternsRequestCondition(new String[] {"/{foo}"}, null, null, false);
|
||||||
|
match = condition.getMatchingCondition(request);
|
||||||
|
|
||||||
|
assertNotNull(match);
|
||||||
|
assertEquals("/{foo}", match.getPatterns().iterator().next());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void matchImplicitTrailingSlash() {
|
public void matchTrailingSlash() {
|
||||||
|
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo/");
|
||||||
|
|
||||||
PatternsRequestCondition condition = new PatternsRequestCondition("/foo");
|
PatternsRequestCondition condition = new PatternsRequestCondition("/foo");
|
||||||
PatternsRequestCondition match = condition.getMatchingCondition(new MockHttpServletRequest("GET", "/foo/"));
|
PatternsRequestCondition match = condition.getMatchingCondition(request);
|
||||||
|
|
||||||
assertNotNull(match);
|
assertNotNull(match);
|
||||||
assertEquals("/foo/", match.getPatterns().iterator().next());
|
assertEquals("/foo/", match.getPatterns().iterator().next());
|
||||||
|
|
||||||
|
boolean useSuffixPatternMatch = false;
|
||||||
|
condition = new PatternsRequestCondition(new String[] {"/foo"}, null, null, useSuffixPatternMatch);
|
||||||
|
match = condition.getMatchingCondition(request);
|
||||||
|
|
||||||
|
assertNotNull(match);
|
||||||
|
assertEquals("Trailing slash should be insensitive to useSuffixPatternMatch settings (SPR-6164, SPR-5636)",
|
||||||
|
"/foo/", match.getPatterns().iterator().next());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
|
|
@ -268,7 +268,7 @@ public class RequestMappingInfoHandlerMappingTests {
|
||||||
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
|
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
|
||||||
RequestMapping annotation = AnnotationUtils.findAnnotation(method, RequestMapping.class);
|
RequestMapping annotation = AnnotationUtils.findAnnotation(method, RequestMapping.class);
|
||||||
return new RequestMappingInfo(
|
return new RequestMappingInfo(
|
||||||
new PatternsRequestCondition(annotation.value(), getUrlPathHelper(), getPathMatcher()),
|
new PatternsRequestCondition(annotation.value(), getUrlPathHelper(), getPathMatcher(), true),
|
||||||
new RequestMethodsRequestCondition(annotation.method()),
|
new RequestMethodsRequestCondition(annotation.method()),
|
||||||
new ParamsRequestCondition(annotation.params()),
|
new ParamsRequestCondition(annotation.params()),
|
||||||
new HeadersRequestCondition(annotation.headers()),
|
new HeadersRequestCondition(annotation.headers()),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue