提交 cf5d5517 编写于 作者: R Rossen Stoyanchev

Pattern suffix issue in AnnotationMethodHandlerAdapter

SPR-9333
上级 ae216fbb
......@@ -208,7 +208,7 @@ public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping {
*/
protected void validateHandler(Object handler, HttpServletRequest request) throws Exception {
}
/**
* Build a handler object for the given raw handler, exposing the actual
* handler, the {@link #PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE}, as well as
......
......@@ -588,7 +588,8 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator
if (!typeLevelPattern.startsWith("/")) {
typeLevelPattern = "/" + typeLevelPattern;
}
if (getMatchingPattern(typeLevelPattern, lookupPath) != null) {
boolean useSuffixPattern = useSuffixPattern(request);
if (getMatchingPattern(typeLevelPattern, lookupPath, useSuffixPattern) != null) {
if (mappingInfo.matches(request)) {
match = true;
mappingInfo.addMatchedPattern(typeLevelPattern);
......@@ -675,6 +676,11 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator
return (Boolean) request.getAttribute(HandlerMapping.INTROSPECT_TYPE_LEVEL_MAPPING);
}
private boolean useSuffixPattern(HttpServletRequest request) {
Object value = request.getAttribute(DefaultAnnotationHandlerMapping.USE_DEFAULT_SUFFIX_PATTERN);
return (value != null) ? (Boolean) value : Boolean.TRUE;
}
/**
* Determines the combined pattern for the given methodLevelPattern and path.
* <p>Uses the following algorithm:
......@@ -687,6 +693,7 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator
* </ol>
*/
private String getCombinedPattern(String methodLevelPattern, String lookupPath, HttpServletRequest request) {
boolean useSuffixPattern = useSuffixPattern(request);
if (useTypeLevelMapping(request)) {
String[] typeLevelPatterns = getTypeLevelMapping().value();
for (String typeLevelPattern : typeLevelPatterns) {
......@@ -694,7 +701,7 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator
typeLevelPattern = "/" + typeLevelPattern;
}
String combinedPattern = pathMatcher.combine(typeLevelPattern, methodLevelPattern);
String matchingPattern = getMatchingPattern(combinedPattern, lookupPath);
String matchingPattern = getMatchingPattern(combinedPattern, lookupPath, useSuffixPattern);
if (matchingPattern != null) {
return matchingPattern;
}
......@@ -704,20 +711,20 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator
String bestMatchingPattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
if (StringUtils.hasText(bestMatchingPattern) && bestMatchingPattern.endsWith("*")) {
String combinedPattern = pathMatcher.combine(bestMatchingPattern, methodLevelPattern);
String matchingPattern = getMatchingPattern(combinedPattern, lookupPath);
String matchingPattern = getMatchingPattern(combinedPattern, lookupPath, useSuffixPattern);
if (matchingPattern != null && !matchingPattern.equals(bestMatchingPattern)) {
return matchingPattern;
}
}
return getMatchingPattern(methodLevelPattern, lookupPath);
return getMatchingPattern(methodLevelPattern, lookupPath, useSuffixPattern);
}
private String getMatchingPattern(String pattern, String lookupPath) {
private String getMatchingPattern(String pattern, String lookupPath, boolean useSuffixPattern) {
if (pattern.equals(lookupPath)) {
return pattern;
}
boolean hasSuffix = pattern.indexOf('.') != -1;
if (!hasSuffix) {
if (useSuffixPattern && !hasSuffix) {
String patternWithSuffix = pattern + ".*";
if (pathMatcher.match(patternWithSuffix, lookupPath)) {
return patternWithSuffix;
......@@ -727,7 +734,7 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator
return pattern;
}
boolean endsWithSlash = pattern.endsWith("/");
if (!endsWithSlash) {
if (useSuffixPattern && !endsWithSlash) {
String patternWithSlash = pattern + "/";
if (pathMatcher.match(patternWithSlash, lookupPath)) {
return patternWithSlash;
......@@ -1236,7 +1243,7 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator
private int compareAcceptHeaders(RequestMappingInfo info1, RequestMappingInfo info2) {
List<MediaType> requestAccepts = request.getHeaders().getAccept();
MediaType.sortByQualityValue(requestAccepts);
List<MediaType> info1Accepts = getAcceptHeaderValue(info1);
List<MediaType> info2Accepts = getAcceptHeaderValue(info2);
......
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -22,6 +22,7 @@ import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import org.springframework.context.ApplicationContext;
......@@ -81,9 +82,11 @@ import org.springframework.web.servlet.handler.AbstractDetectingUrlHandlerMappin
*/
public class DefaultAnnotationHandlerMapping extends AbstractDetectingUrlHandlerMapping {
static final String USE_DEFAULT_SUFFIX_PATTERN = DefaultAnnotationHandlerMapping.class.getName() + ".useDefaultSuffixPattern";
private boolean useDefaultSuffixPattern = true;
private final Map<Class, RequestMapping> cachedMappings = new HashMap<Class, RequestMapping>();
private final Map<Class<?>, RequestMapping> cachedMappings = new HashMap<Class<?>, RequestMapping>();
/**
......@@ -229,6 +232,7 @@ public class DefaultAnnotationHandlerMapping extends AbstractDetectingUrlHandler
if (mapping != null) {
validateMapping(mapping, request);
}
request.setAttribute(USE_DEFAULT_SUFFIX_PATTERN, this.useDefaultSuffixPattern);
}
/**
......
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -351,6 +351,31 @@ public class UriTemplateServletAnnotationControllerTests {
assertEquals("foo-foo", response.getContentAsString());
}
// SPR-9333
@Test
@SuppressWarnings("serial")
public void suppressDefaultSuffixPattern() throws Exception {
servlet = new DispatcherServlet() {
@Override
protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent)
throws BeansException {
GenericWebApplicationContext wac = new GenericWebApplicationContext();
wac.registerBeanDefinition("controller", new RootBeanDefinition(VariableNamesController.class));
RootBeanDefinition mappingDef = new RootBeanDefinition(DefaultAnnotationHandlerMapping.class);
mappingDef.getPropertyValues().add("useDefaultSuffixPattern", false);
wac.registerBeanDefinition("handlerMapping", mappingDef);
wac.refresh();
return wac;
}
};
servlet.init(new MockServletConfig());
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/test/jsmith@mail.com");
MockHttpServletResponse response = new MockHttpServletResponse();
servlet.service(request, response);
assertEquals("foo-jsmith@mail.com", response.getContentAsString());
}
// SPR-6906
@Test
public void controllerClassName() throws Exception {
......@@ -389,7 +414,7 @@ public class UriTemplateServletAnnotationControllerTests {
@Test
public void doIt() throws Exception {
initServlet(Spr6978Controller.class);
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo/100");
MockHttpServletResponse response = new MockHttpServletResponse();
servlet.service(request, response);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册