revised handler method resolution, in particular with respect to generic interfaces (SPR-7355)
This commit is contained in:
@@ -27,6 +27,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
@@ -496,10 +497,36 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator
|
||||
*/
|
||||
private class ServletHandlerMethodResolver extends HandlerMethodResolver {
|
||||
|
||||
private final Map<Method, RequestMappingInfo> mappings = new HashMap<Method, RequestMappingInfo>();
|
||||
|
||||
private ServletHandlerMethodResolver(Class<?> handlerType) {
|
||||
init(handlerType);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isHandlerMethod(Method method) {
|
||||
if (this.mappings.containsKey(method)) {
|
||||
return true;
|
||||
}
|
||||
RequestMapping mapping = AnnotationUtils.findAnnotation(method, RequestMapping.class);
|
||||
if (mapping != null) {
|
||||
RequestMappingInfo mappingInfo = new RequestMappingInfo();
|
||||
mappingInfo.patterns = mapping.value();
|
||||
if (!hasTypeLevelMapping() || !Arrays.equals(mapping.method(), getTypeLevelMapping().method())) {
|
||||
mappingInfo.methods = mapping.method();
|
||||
}
|
||||
if (!hasTypeLevelMapping() || !Arrays.equals(mapping.params(), getTypeLevelMapping().params())) {
|
||||
mappingInfo.params = mapping.params();
|
||||
}
|
||||
if (!hasTypeLevelMapping() || !Arrays.equals(mapping.headers(), getTypeLevelMapping().headers())) {
|
||||
mappingInfo.headers = mapping.headers();
|
||||
}
|
||||
this.mappings.put(method, mappingInfo);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Method resolveHandlerMethod(HttpServletRequest request) throws ServletException {
|
||||
String lookupPath = urlPathHelper.getLookupPathForRequest(request);
|
||||
Comparator<String> pathComparator = pathMatcher.getPatternComparator(lookupPath);
|
||||
@@ -507,7 +534,7 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator
|
||||
Set<String> allowedMethods = new LinkedHashSet<String>(7);
|
||||
String resolvedMethodName = null;
|
||||
for (Method handlerMethod : getHandlerMethods()) {
|
||||
RequestMappingInfo mappingInfo = createRequestMappingInfo(handlerMethod);
|
||||
RequestMappingInfo mappingInfo = this.mappings.get(handlerMethod);
|
||||
boolean match = false;
|
||||
if (mappingInfo.hasPatterns()) {
|
||||
List<String> matchingPatterns = new ArrayList<String>(mappingInfo.patterns.length);
|
||||
@@ -599,22 +626,6 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator
|
||||
}
|
||||
}
|
||||
|
||||
private RequestMappingInfo createRequestMappingInfo(Method handlerMethod) {
|
||||
RequestMappingInfo mappingInfo = new RequestMappingInfo();
|
||||
RequestMapping mapping = AnnotationUtils.findAnnotation(handlerMethod, RequestMapping.class);
|
||||
mappingInfo.patterns = mapping.value();
|
||||
if (!hasTypeLevelMapping() || !Arrays.equals(mapping.method(), getTypeLevelMapping().method())) {
|
||||
mappingInfo.methods = mapping.method();
|
||||
}
|
||||
if (!hasTypeLevelMapping() || !Arrays.equals(mapping.params(), getTypeLevelMapping().params())) {
|
||||
mappingInfo.params = mapping.params();
|
||||
}
|
||||
if (!hasTypeLevelMapping() || !Arrays.equals(mapping.headers(), getTypeLevelMapping().headers())) {
|
||||
mappingInfo.headers = mapping.headers();
|
||||
}
|
||||
return mappingInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the combined pattern for the given methodLevelPattern and path.
|
||||
* <p>Uses the following algorithm: <ol>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
package org.springframework.web.servlet.mvc.annotation;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
@@ -165,8 +165,9 @@ public class DefaultAnnotationHandlerMapping extends AbstractDetectingUrlHandler
|
||||
}
|
||||
|
||||
final Set<String> urls = new LinkedHashSet<String>();
|
||||
Class<?>[] handlerTypes =
|
||||
Proxy.isProxyClass(handlerType) ? handlerType.getInterfaces() : new Class<?>[]{handlerType};
|
||||
Set<Class<?>> handlerTypes = new LinkedHashSet<Class<?>>();
|
||||
handlerTypes.add(handlerType);
|
||||
handlerTypes.addAll(Arrays.asList(handlerType.getInterfaces()));
|
||||
for (Class<?> currentHandlerType : handlerTypes) {
|
||||
ReflectionUtils.doWithMethods(currentHandlerType, new ReflectionUtils.MethodCallback() {
|
||||
public void doWith(Method method) {
|
||||
@@ -187,7 +188,7 @@ public class DefaultAnnotationHandlerMapping extends AbstractDetectingUrlHandler
|
||||
}
|
||||
}
|
||||
}
|
||||
}, ReflectionUtils.NON_BRIDGED_METHODS);
|
||||
}, ReflectionUtils.USER_DECLARED_METHODS);
|
||||
}
|
||||
return StringUtils.toStringArray(urls);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user