@ExceptionHandler methods consistently receive original exception as thrown by user methods

git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@3199 50f2f4bb-b051-0410-bef5-90022cba6387
This commit is contained in:
Juergen Hoeller 2010-03-30 23:28:21 +00:00
parent 2dbd0159d7
commit 052d3fd531
1 changed files with 41 additions and 41 deletions

View File

@ -47,8 +47,8 @@ import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.http.HttpEntity; import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage; import org.springframework.http.HttpInputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.HttpOutputMessage; import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.ui.ExtendedModelMap; import org.springframework.ui.ExtendedModelMap;
import org.springframework.ui.Model; import org.springframework.ui.Model;
@ -156,12 +156,11 @@ public class HandlerMethodInvoker {
if (!"".equals(attrName) && implicitModel.containsAttribute(attrName)) { if (!"".equals(attrName) && implicitModel.containsAttribute(attrName)) {
continue; continue;
} }
Object attrValue = doInvokeMethod(attributeMethodToInvoke, handler, args); ReflectionUtils.makeAccessible(attributeMethodToInvoke);
Object attrValue = attributeMethodToInvoke.invoke(handler, args);
if ("".equals(attrName)) { if ("".equals(attrName)) {
Class resolvedType = Class resolvedType = GenericTypeResolver.resolveReturnType(attributeMethodToInvoke, handler.getClass());
GenericTypeResolver.resolveReturnType(attributeMethodToInvoke, handler.getClass()); attrName = Conventions.getVariableNameForReturnType(attributeMethodToInvoke, resolvedType, attrValue);
attrName =
Conventions.getVariableNameForReturnType(attributeMethodToInvoke, resolvedType, attrValue);
} }
if (!implicitModel.containsAttribute(attrName)) { if (!implicitModel.containsAttribute(attrName)) {
implicitModel.addAttribute(attrName, attrValue); implicitModel.addAttribute(attrName, attrValue);
@ -171,12 +170,19 @@ public class HandlerMethodInvoker {
if (debug) { if (debug) {
logger.debug("Invoking request handler method: " + handlerMethodToInvoke); logger.debug("Invoking request handler method: " + handlerMethodToInvoke);
} }
return doInvokeMethod(handlerMethodToInvoke, handler, args); ReflectionUtils.makeAccessible(handlerMethodToInvoke);
return handlerMethodToInvoke.invoke(handler, args);
} }
catch (IllegalStateException ex) { catch (IllegalStateException ex) {
// Throw exception with full handler method context... // Internal assertion failed (e.g. invalid signature):
// throw exception with full handler method context...
throw new HandlerMethodInvocationException(handlerMethodToInvoke, ex); throw new HandlerMethodInvocationException(handlerMethodToInvoke, ex);
} }
catch (InvocationTargetException ex) {
// User-defined @ModelAttribute/@InitBinder/@RequestMapping method threw an exception...
ReflectionUtils.rethrowException(ex.getTargetException());
return null;
}
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -336,7 +342,8 @@ public class HandlerMethodInvoker {
if (debug) { if (debug) {
logger.debug("Invoking init-binder method: " + methodToInvoke); logger.debug("Invoking init-binder method: " + methodToInvoke);
} }
Object returnValue = doInvokeMethod(methodToInvoke, handler, initBinderArgs); ReflectionUtils.makeAccessible(methodToInvoke);
Object returnValue = methodToInvoke.invoke(handler, initBinderArgs);
if (returnValue != null) { if (returnValue != null) {
throw new IllegalStateException( throw new IllegalStateException(
"InitBinder methods must not have a return value: " + methodToInvoke); "InitBinder methods must not have a return value: " + methodToInvoke);
@ -395,9 +402,8 @@ public class HandlerMethodInvoker {
paramName = ""; paramName = "";
} }
else { else {
throw new IllegalStateException( throw new IllegalStateException("Unsupported argument [" + paramType.getName() +
"Unsupported argument [" + paramType.getName() + "] for @InitBinder method: " + "] for @InitBinder method: " + initBinderMethod);
initBinderMethod);
} }
} }
} }
@ -724,6 +730,7 @@ public class HandlerMethodInvoker {
// Expose model attributes as session attributes, if required. // Expose model attributes as session attributes, if required.
// Expose BindingResults for all attributes, making custom editors available. // Expose BindingResults for all attributes, making custom editors available.
Map<String, Object> model = (mavModel != null ? mavModel : implicitModel); Map<String, Object> model = (mavModel != null ? mavModel : implicitModel);
try {
for (String attrName : new HashSet<String>(model.keySet())) { for (String attrName : new HashSet<String>(model.keySet())) {
Object attrValue = model.get(attrName); Object attrValue = model.get(attrName);
boolean isSessionAttr = boolean isSessionAttr =
@ -742,6 +749,11 @@ public class HandlerMethodInvoker {
} }
} }
} }
catch (InvocationTargetException ex) {
// User-defined @InitBinder method threw an exception...
ReflectionUtils.rethrowException(ex.getTargetException());
}
}
/** /**
* Determine whether the given value qualifies as a "binding candidate", i.e. might potentially be subject to * Determine whether the given value qualifies as a "binding candidate", i.e. might potentially be subject to
@ -752,17 +764,6 @@ public class HandlerMethodInvoker {
!(value instanceof Map) && !BeanUtils.isSimpleValueType(value.getClass())); !(value instanceof Map) && !BeanUtils.isSimpleValueType(value.getClass()));
} }
private Object doInvokeMethod(Method method, Object target, Object[] args) throws Exception {
ReflectionUtils.makeAccessible(method);
try {
return method.invoke(target, args);
}
catch (InvocationTargetException ex) {
ReflectionUtils.rethrowException(ex.getTargetException());
}
throw new IllegalStateException("Should never get here");
}
protected void raiseMissingParameterException(String paramName, Class paramType) throws Exception { protected void raiseMissingParameterException(String paramName, Class paramType) throws Exception {
throw new IllegalStateException("Missing parameter '" + paramName + "' of type [" + paramType.getName() + "]"); throw new IllegalStateException("Missing parameter '" + paramName + "' of type [" + paramType.getName() + "]");
} }
@ -843,9 +844,8 @@ public class HandlerMethodInvoker {
Class paramType = methodParameter.getParameterType(); Class paramType = methodParameter.getParameterType();
Object value = resolveStandardArgument(paramType, webRequest); Object value = resolveStandardArgument(paramType, webRequest);
if (value != WebArgumentResolver.UNRESOLVED && !ClassUtils.isAssignableValue(paramType, value)) { if (value != WebArgumentResolver.UNRESOLVED && !ClassUtils.isAssignableValue(paramType, value)) {
throw new IllegalStateException( throw new IllegalStateException("Standard argument type [" + paramType.getName() +
"Standard argument type [" + paramType.getName() + "] resolved to incompatible value of type [" + "] resolved to incompatible value of type [" + (value != null ? value.getClass() : null) +
(value != null ? value.getClass() : null) +
"]. Consider declaring the argument type in a less specific fashion."); "]. Consider declaring the argument type in a less specific fashion.");
} }
return value; return value;