This commit is contained in:
Rossen Stoyanchev
2011-04-15 06:42:18 +00:00
parent f5f738f2b4
commit 83ce399c47
8 changed files with 80 additions and 45 deletions

View File

@@ -97,29 +97,30 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
/**
* Detect and register handler methods for the specified handler.
*/
private void detectHandlerMethods(final String handlerName) {
Class<?> handlerType = getApplicationContext().getType(handlerName);
private void detectHandlerMethods(final String beanName) {
Class<?> handlerType = getApplicationContext().getType(beanName);
Set<Method> methods = HandlerMethodSelector.selectMethods(handlerType, new MethodFilter() {
public boolean matches(Method method) {
return getKeyForMethod(method) != null;
return getKeyForMethod(beanName, method) != null;
}
});
for (Method method : methods) {
T key = getKeyForMethod(method);
HandlerMethod handlerMethod = new HandlerMethod(handlerName, getApplicationContext(), method);
T key = getKeyForMethod(beanName, method);
HandlerMethod handlerMethod = new HandlerMethod(beanName, getApplicationContext(), method);
registerHandlerMethod(key, handlerMethod);
}
}
/**
* Provides a lookup key for the given method. A method for which no key can be determined is
* Provides a lookup key for the given bean method. A method for which no key can be determined is
* not considered a handler method.
*
* @param beanName the name of the bean the method belongs to
* @param method the method to create a key for
* @return the lookup key, or {@code null} if the method has none
*/
protected abstract T getKeyForMethod(Method method);
protected abstract T getKeyForMethod(String beanName, Method method);
/**
* Registers a {@link HandlerMethod} under the given key.
@@ -133,12 +134,13 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
Assert.notNull(handlerMethod, "'handlerMethod' must not be null");
HandlerMethod mappedHandlerMethod = handlerMethods.get(key);
if (mappedHandlerMethod != null && !mappedHandlerMethod.equals(handlerMethod)) {
throw new IllegalStateException("Cannot map " + handlerMethod + " to \"" + key + "\": There is already "
+ mappedHandlerMethod + " mapped.");
throw new IllegalStateException("Ambiguous mapping found. Cannot map '" + handlerMethod.getBean()
+ "' bean method \n" + handlerMethod + "\nto " + key + ": There is already '"
+ mappedHandlerMethod.getBean() + "' bean method\n" + mappedHandlerMethod + " mapped.");
}
handlerMethods.put(key, handlerMethod);
if (logger.isDebugEnabled()) {
logger.debug("Mapped \"" + key + "\" onto " + handlerMethod);
if (logger.isInfoEnabled()) {
logger.info("Mapped \"" + key + "\" onto " + handlerMethod);
}
}
@@ -149,14 +151,14 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
return null;
}
if (logger.isDebugEnabled()) {
logger.debug("Looking up handler method for [" + key + "]");
logger.debug("Looking up handler method with key [" + key + "]");
}
HandlerMethod handlerMethod = lookupHandlerMethod(key, request);
if (logger.isDebugEnabled()) {
if (handlerMethod != null) {
logger.debug("Returning [" + handlerMethod + "] as best match for [" + key + "]");
logger.debug("Returning handler method [" + handlerMethod + "]");
}
else {
logger.debug("Did not find handler method for [" + key + "]");

View File

@@ -161,16 +161,17 @@ public class RequestMappingHandlerMethodMapping extends AbstractHandlerMethodMap
* Type-level {@link RequestMapping @RequestMapping} annotations are also detected and their
* attributes combined with method-level {@link RequestMapping @RequestMapping} attributes.
*
* @param beanName the name of the bean the method belongs to
* @param method the method to create a key for
* @return the key, or {@code null}
* @see RequestKey#combine(RequestKey, PathMatcher)
*/
@Override
protected RequestKey getKeyForMethod(Method method) {
protected RequestKey getKeyForMethod(String beanName, Method method) {
RequestMapping annotation = AnnotationUtils.findAnnotation(method, RequestMapping.class);
if (annotation != null) {
RequestKey methodKey = RequestKey.createFromRequestMapping(annotation);
RequestMapping typeAnnot = AnnotationUtils.findAnnotation(method.getDeclaringClass(), RequestMapping.class);
RequestMapping typeAnnot = getApplicationContext().findAnnotationOnBean(beanName, RequestMapping.class);
if (typeAnnot != null) {
RequestKey typeKey = RequestKey.createFromRequestMapping(typeAnnot);
return typeKey.combine(methodKey, pathMatcher);

View File

@@ -25,9 +25,9 @@ import org.springframework.web.servlet.View;
/**
* Handles return values that are of type {@link View} or {@link String} (i.e. a logical view name).
* <p>Since {@link String} return value can be interpeted in multiple ways, this resolver should be ordered
* after return value handlers that recognize annotated return values such as the
* {@link ModelAttributeMethodProcessor} and the {@link RequestResponseBodyMethodProcessor}.
* <p>Since a {@link String} return value may handled in different ways, especially in combination with method
* annotations, this handler should be registered after return value handlers that look for method annotations
* such as the {@link ModelAttributeMethodProcessor} and the {@link RequestResponseBodyMethodProcessor}.
*
* @author Rossen Stoyanchev
* @since 3.1

View File

@@ -60,4 +60,13 @@ class ConsumesRequestCondition extends AbstractRequestCondition {
return false;
}
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
if (mediaType != null) {
builder.append(mediaType.toString());
}
return builder.toString();
}
}