Fix issue in AnnotationMethodHandlerExceptionResolver

Caching of resovled exceptions introduced in SPR-7703 also introduced a
side effect whereby if exactly one exception was previously cached, any
other exception would appear as a match to the previously matched
@ExceptionHandler method.

This change ensures use of a fresh map when determining matching
@ExceptionHandler methods while also updating the cache.

Issue: SPR-9209
This commit is contained in:
Rossen Stoyanchev
2012-10-06 22:03:31 -04:00
parent 470c85ade0
commit ec2603de63
4 changed files with 48 additions and 14 deletions

View File

@@ -25,6 +25,7 @@ import java.lang.reflect.Method;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -147,7 +148,7 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
exceptionHandlerCache.put(handlerType, handlers);
}
final Map<Class<? extends Throwable>, Method> resolverMethods = handlers;
final Map<Class<? extends Throwable>, Method> matchedHandlers = new HashMap<Class<? extends Throwable>, Method>();
ReflectionUtils.doWithMethods(handlerType, new ReflectionUtils.MethodCallback() {
public void doWith(Method method) {
@@ -155,11 +156,11 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
List<Class<? extends Throwable>> handledExceptions = getHandledExceptions(method);
for (Class<? extends Throwable> handledException : handledExceptions) {
if (handledException.isAssignableFrom(thrownExceptionType)) {
if (!resolverMethods.containsKey(handledException)) {
resolverMethods.put(handledException, method);
if (!matchedHandlers.containsKey(handledException)) {
matchedHandlers.put(handledException, method);
}
else {
Method oldMappedMethod = resolverMethods.get(handledException);
Method oldMappedMethod = matchedHandlers.get(handledException);
if (!oldMappedMethod.equals(method)) {
throw new IllegalStateException(
"Ambiguous exception handler mapped for " + handledException + "]: {" +
@@ -171,7 +172,7 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
}
});
handlerMethod = getBestMatchingMethod(resolverMethods, thrownException);
handlerMethod = getBestMatchingMethod(matchedHandlers, thrownException);
handlers.put(thrownExceptionType, (handlerMethod == null ? NO_METHOD_FOUND : handlerMethod));
return handlerMethod;
}