SPR-8447 Provide sufficient contextwherever possible when exceptions are raised in new @MVC classes.
This commit is contained in:
@@ -64,7 +64,7 @@ public class InitBinderDataBinderFactory extends DefaultDataBinderFactory {
|
||||
}
|
||||
Object returnValue = binderMethod.invokeForRequest(request, null, binder);
|
||||
if (returnValue != null) {
|
||||
throw new IllegalStateException("This @InitBinder method does not return void: " + binderMethod);
|
||||
throw new IllegalStateException("@InitBinder methods should return void: " + binderMethod);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +141,8 @@ public final class ModelFactory {
|
||||
if (sessionHandler.isHandlerSessionAttribute(name, parameter.getParameterType())) {
|
||||
Object attrValue = sessionHandler.retrieveAttribute(request, name);
|
||||
if (attrValue == null){
|
||||
throw new HttpSessionRequiredException("Session attribute '" + name + "' not found in session");
|
||||
throw new HttpSessionRequiredException(
|
||||
"Session attribute '" + name + "' not found in session: " + requestMethod);
|
||||
}
|
||||
mavContainer.addAttribute(name, attrValue);
|
||||
}
|
||||
|
||||
@@ -99,9 +99,9 @@ public abstract class AbstractWebArgumentResolverAdapter implements HandlerMetho
|
||||
Object result = adaptee.resolveArgument(parameter, webRequest);
|
||||
if (result == WebArgumentResolver.UNRESOLVED || !ClassUtils.isAssignableValue(paramType, result)) {
|
||||
throw new IllegalStateException(
|
||||
"Standard argument type [" + paramType.getName() + "] resolved to incompatible value of type [" +
|
||||
(result != null ? result.getClass() : null) +
|
||||
"]. Consider declaring the argument type in a less specific fashion.");
|
||||
"Standard argument type [" + paramType.getName() + "] in method " + parameter.getMethod() +
|
||||
"resolved to incompatible value of type [" + (result != null ? result.getClass() : null) +
|
||||
"]. Consider declaring the argument type in a less specific fashion.");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -56,8 +56,9 @@ public class ErrorsMethodArgumentResolver implements HandlerMethodArgumentResolv
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Errors/BindingResult argument declared "
|
||||
+ "without preceding model attribute. Check your handler method signature!");
|
||||
throw new IllegalStateException(
|
||||
"An Errors/BindingResult argument must follow a model attribute argument. " +
|
||||
"Check your handler method signature: " + parameter.getMethod());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -66,7 +66,7 @@ public class ExpressionValueMethodArgumentResolver extends AbstractNamedValueMet
|
||||
|
||||
@Override
|
||||
protected void handleMissingValue(String name, MethodParameter parameter) throws ServletException {
|
||||
throw new UnsupportedOperationException("Did not expect to handle a missing value: an @Value is never required");
|
||||
throw new UnsupportedOperationException("@Value is never required: " + parameter.getMethod());
|
||||
}
|
||||
|
||||
private static class ExpressionValueNamedValueInfo extends NamedValueInfo {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.web.method.annotation.support;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
@@ -76,7 +77,9 @@ public class ModelMethodProcessor implements HandlerMethodArgumentResolver, Hand
|
||||
}
|
||||
else {
|
||||
// should not happen
|
||||
throw new UnsupportedOperationException();
|
||||
Method method = returnType.getMethod();
|
||||
String returnTypeName = returnType.getParameterType().getName();
|
||||
throw new UnsupportedOperationException("Unknown return type: " + returnTypeName + " in method: " + method);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.bind.support.WebDataBinderFactory;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
|
||||
@@ -61,14 +62,8 @@ public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgu
|
||||
NativeWebRequest webRequest,
|
||||
WebDataBinderFactory binderFactory) throws Exception {
|
||||
HandlerMethodArgumentResolver resolver = getArgumentResolver(parameter);
|
||||
if (resolver != null) {
|
||||
return resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory);
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException(
|
||||
"No suitable HandlerMethodArgumentResolver found. " +
|
||||
"supportsParameter(MethodParameter) should have been called previously.");
|
||||
}
|
||||
Assert.notNull(resolver, "Unknown parameter type [" + parameter.getParameterType().getName() + "]");
|
||||
return resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
|
||||
/**
|
||||
@@ -60,14 +61,8 @@ public class HandlerMethodReturnValueHandlerComposite implements HandlerMethodRe
|
||||
ModelAndViewContainer mavContainer,
|
||||
NativeWebRequest webRequest) throws Exception {
|
||||
HandlerMethodReturnValueHandler handler = getReturnValueHandler(returnType);
|
||||
if (handler != null) {
|
||||
handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest);
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException(
|
||||
"No suitable HandlerMethodReturnValueHandler found. " +
|
||||
"supportsReturnType(MethodParameter) should have been called previously");
|
||||
}
|
||||
Assert.notNull(handler, "Unknown return value type [" + returnType.getParameterType().getName() + "]");
|
||||
handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -142,25 +142,52 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
||||
Object[] args = new Object[parameters.length];
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
MethodParameter parameter = parameters[i];
|
||||
parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);
|
||||
parameter.initParameterNameDiscovery(parameterNameDiscoverer);
|
||||
GenericTypeResolver.resolveParameterType(parameter, getBean().getClass());
|
||||
|
||||
args[i] = resolveProvidedArgument(parameter, providedArgs);
|
||||
if (args[i] != null) {
|
||||
continue;
|
||||
}
|
||||
if (this.argumentResolvers.supportsParameter(parameter)) {
|
||||
args[i] = this.argumentResolvers.resolveArgument(parameter, mavContainer, request, dataBinderFactory);
|
||||
|
||||
if (argumentResolvers.supportsParameter(parameter)) {
|
||||
try {
|
||||
args[i] = argumentResolvers.resolveArgument(parameter, mavContainer, request, dataBinderFactory);
|
||||
continue;
|
||||
} catch (Exception ex) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace(getArgumentResolutionErrorMessage("Error resolving argument", i), ex);
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("Cannot resolve argument index=" + parameter.getParameterIndex() + ""
|
||||
+ ", name=" + parameter.getParameterName() + ", type=" + parameter.getParameterType()
|
||||
+ " in method " + toString());
|
||||
|
||||
if (args[i] == null) {
|
||||
String msg = getArgumentResolutionErrorMessage("No suitable resolver for argument", i);
|
||||
throw new IllegalStateException(msg);
|
||||
}
|
||||
}
|
||||
return args;
|
||||
}
|
||||
|
||||
private String getArgumentResolutionErrorMessage(String message, int index) {
|
||||
MethodParameter param = getMethodParameters()[index];
|
||||
message += " [" + index + "] [type=" + param.getParameterType().getName() + "]";
|
||||
return getDetailedErrorMessage(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds HandlerMethod details such as the controller type and method signature to the given error message.
|
||||
* @param message error message to append the HandlerMethod details to
|
||||
*/
|
||||
protected String getDetailedErrorMessage(String message) {
|
||||
StringBuilder sb = new StringBuilder(message).append("\n");
|
||||
sb.append("HandlerMethod details: \n");
|
||||
sb.append("Controller [").append(getBeanType().getName()).append("]\n");
|
||||
sb.append("Method [").append(getBridgedMethod().toGenericString()).append("]\n");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to resolve a method parameter from the list of provided argument values.
|
||||
*/
|
||||
@@ -177,55 +204,50 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke this handler method with the given argument values.
|
||||
* Invoke the handler method with the given argument values.
|
||||
*/
|
||||
private Object invoke(Object... args) throws Exception {
|
||||
ReflectionUtils.makeAccessible(this.getBridgedMethod());
|
||||
try {
|
||||
return getBridgedMethod().invoke(getBean(), args);
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
handleIllegalArgumentException(ex, args);
|
||||
throw ex;
|
||||
catch (IllegalArgumentException e) {
|
||||
String msg = getInvocationErrorMessage(e.getMessage(), args);
|
||||
throw new IllegalArgumentException(msg, e);
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
handleInvocationTargetException(ex);
|
||||
throw new IllegalStateException(
|
||||
"Unexpected exception thrown by method - " + ex.getTargetException().getClass().getName() + ": " +
|
||||
ex.getTargetException().getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void handleIllegalArgumentException(IllegalArgumentException ex, Object... args) {
|
||||
StringBuilder builder = new StringBuilder(ex.getMessage());
|
||||
builder.append(" :: method=").append(getBridgedMethod().toGenericString());
|
||||
builder.append(" :: invoked with handler type=").append(getBeanType().getName());
|
||||
|
||||
if (args != null && args.length > 0) {
|
||||
builder.append(" and argument types ");
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
String argClass = (args[i] != null) ? args[i].getClass().toString() : "null";
|
||||
builder.append(" : arg[").append(i).append("] ").append(argClass);
|
||||
catch (InvocationTargetException e) {
|
||||
// Unwrap for HandlerExceptionResolvers ...
|
||||
Throwable targetException = e.getTargetException();
|
||||
if (targetException instanceof RuntimeException) {
|
||||
throw (RuntimeException) targetException;
|
||||
}
|
||||
else if (targetException instanceof Error) {
|
||||
throw (Error) targetException;
|
||||
}
|
||||
else if (targetException instanceof Exception) {
|
||||
throw (Exception) targetException;
|
||||
}
|
||||
else {
|
||||
String msg = getInvocationErrorMessage("Failed to invoke controller method", args);
|
||||
throw new IllegalStateException(msg, targetException);
|
||||
}
|
||||
}
|
||||
else {
|
||||
builder.append(" and 0 arguments");
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(builder.toString(), ex);
|
||||
}
|
||||
|
||||
private void handleInvocationTargetException(InvocationTargetException ex) throws Exception {
|
||||
Throwable targetException = ex.getTargetException();
|
||||
if (targetException instanceof RuntimeException) {
|
||||
throw (RuntimeException) targetException;
|
||||
}
|
||||
if (targetException instanceof Error) {
|
||||
throw (Error) targetException;
|
||||
}
|
||||
if (targetException instanceof Exception) {
|
||||
throw (Exception) targetException;
|
||||
private String getInvocationErrorMessage(String message, Object[] resolvedArgs) {
|
||||
StringBuilder sb = new StringBuilder(getDetailedErrorMessage(message));
|
||||
sb.append("Resolved arguments: \n");
|
||||
for (int i=0; i < resolvedArgs.length; i++) {
|
||||
sb.append("[").append(i).append("] ");
|
||||
if (resolvedArgs[i] == null) {
|
||||
sb.append("[null] \n");
|
||||
}
|
||||
else {
|
||||
sb.append("[type=").append(resolvedArgs[i].getClass().getName()).append("] ");
|
||||
sb.append("[value=").append(resolvedArgs[i]).append("]\n");
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -73,7 +73,7 @@ public class HandlerMethodArgumentResolverCompositeTests {
|
||||
assertEquals("Didn't use the first registered resolver", Integer.valueOf(1), resolvedValue);
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void noSuitableArgumentResolver() throws Exception {
|
||||
this.resolvers.resolveArgument(paramStr, null, null, null);
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ public class HandlerMethodReturnValueHandlerCompositeTests {
|
||||
assertNull("Shouldn't have use the 2nd registered handler", h2.getReturnValue());
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void noSuitableReturnValueHandler() throws Exception {
|
||||
registerHandler(Integer.class);
|
||||
this.handlers.handleReturnValue("value", paramStr, null, null);
|
||||
|
||||
@@ -17,89 +17,223 @@
|
||||
package org.springframework.web.method.support;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.support.WebDataBinderFactory;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
|
||||
/**
|
||||
* Test fixture with {@link InvocableHandlerMethod}.
|
||||
* Test fixture for {@link InvocableHandlerMethod} unit tests.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class InvocableHandlerMethodTests {
|
||||
|
||||
private HandlerMethodArgumentResolverComposite argumentResolvers;
|
||||
private InvocableHandlerMethod handleMethod;
|
||||
|
||||
private NativeWebRequest webRequest;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
argumentResolvers = new HandlerMethodArgumentResolverComposite();
|
||||
Method method = Handler.class.getDeclaredMethod("handle", Integer.class, String.class);
|
||||
this.handleMethod = new InvocableHandlerMethod(new Handler(), method);
|
||||
this.webRequest = new ServletWebRequest(new MockHttpServletRequest(), new MockHttpServletResponse());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveArgument() throws Exception {
|
||||
StubArgumentResolver intResolver = addResolver(Integer.class, 99);
|
||||
StubArgumentResolver strResolver = addResolver(String.class, "value");
|
||||
InvocableHandlerMethod method = invocableHandlerMethod("handle", Integer.class, String.class);
|
||||
Object returnValue = method.invokeForRequest(webRequest, null);
|
||||
|
||||
assertEquals("Integer resolver not invoked", 1, intResolver.getResolvedParameters().size());
|
||||
assertEquals("String resolver not invoked", 1, strResolver.getResolvedParameters().size());
|
||||
assertEquals("Invalid return value", "99-value", returnValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveProvidedArgument() throws Exception {
|
||||
InvocableHandlerMethod method = invocableHandlerMethod("handle", Integer.class, String.class);
|
||||
Object returnValue = method.invokeForRequest(webRequest, null, 99, "value");
|
||||
public void resolveArg() throws Exception {
|
||||
StubArgumentResolver intResolver = new StubArgumentResolver(Integer.class, 99);
|
||||
StubArgumentResolver stringResolver = new StubArgumentResolver(String.class, "value");
|
||||
|
||||
assertEquals("Expected raw return value with no handlers registered", String.class, returnValue.getClass());
|
||||
assertEquals("Provided argument values were not resolved", "99-value", returnValue);
|
||||
HandlerMethodArgumentResolverComposite composite = new HandlerMethodArgumentResolverComposite();
|
||||
composite.addResolver(intResolver);
|
||||
composite.addResolver(stringResolver);
|
||||
handleMethod.setHandlerMethodArgumentResolvers(composite);
|
||||
|
||||
Object returnValue = handleMethod.invokeForRequest(webRequest, null);
|
||||
|
||||
assertEquals(1, intResolver.getResolvedParameters().size());
|
||||
assertEquals(1, stringResolver.getResolvedParameters().size());
|
||||
assertEquals("99-value", returnValue);
|
||||
|
||||
assertEquals("intArg", intResolver.getResolvedParameters().get(0).getParameterName());
|
||||
assertEquals("stringArg", stringResolver.getResolvedParameters().get(0).getParameterName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void discoverParameterName() throws Exception {
|
||||
StubArgumentResolver resolver = addResolver(Integer.class, 99);
|
||||
InvocableHandlerMethod method = invocableHandlerMethod("parameterNameDiscovery", Integer.class);
|
||||
method.invokeForRequest(webRequest, null);
|
||||
public void resolveNullArg() throws Exception {
|
||||
StubArgumentResolver intResolver = new StubArgumentResolver(Integer.class, null);
|
||||
StubArgumentResolver stringResolver = new StubArgumentResolver(String.class, null);
|
||||
|
||||
HandlerMethodArgumentResolverComposite composite = new HandlerMethodArgumentResolverComposite();
|
||||
composite.addResolver(intResolver);
|
||||
composite.addResolver(stringResolver);
|
||||
handleMethod.setHandlerMethodArgumentResolvers(composite);
|
||||
|
||||
assertEquals("intArg", resolver.getResolvedParameters().get(0).getParameterName());
|
||||
Object returnValue = handleMethod.invokeForRequest(webRequest, null);
|
||||
|
||||
assertEquals(1, intResolver.getResolvedParameters().size());
|
||||
assertEquals(1, stringResolver.getResolvedParameters().size());
|
||||
assertEquals("null-null", returnValue);
|
||||
}
|
||||
|
||||
private StubArgumentResolver addResolver(Class<?> parameterType, Object stubValue) {
|
||||
StubArgumentResolver resolver = new StubArgumentResolver(parameterType, stubValue);
|
||||
argumentResolvers.addResolver(resolver);
|
||||
return resolver;
|
||||
@Test
|
||||
public void cannotResolveArg() throws Exception {
|
||||
try {
|
||||
handleMethod.invokeForRequest(webRequest, null);
|
||||
fail("Expected exception");
|
||||
} catch (IllegalStateException ex) {
|
||||
assertTrue(ex.getMessage().contains("No suitable resolver for argument [0] [type=java.lang.Integer]"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveProvidedArg() throws Exception {
|
||||
Object returnValue = handleMethod.invokeForRequest(webRequest, null, 99, "value");
|
||||
|
||||
assertEquals(String.class, returnValue.getClass());
|
||||
assertEquals("99-value", returnValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveProvidedArgFirst() throws Exception {
|
||||
StubArgumentResolver intResolver = new StubArgumentResolver(Integer.class, 1);
|
||||
StubArgumentResolver stringResolver = new StubArgumentResolver(String.class, "value1");
|
||||
|
||||
HandlerMethodArgumentResolverComposite composite = new HandlerMethodArgumentResolverComposite();
|
||||
composite.addResolver(intResolver);
|
||||
composite.addResolver(stringResolver);
|
||||
handleMethod.setHandlerMethodArgumentResolvers(composite);
|
||||
|
||||
Object returnValue = handleMethod.invokeForRequest(webRequest, null, 2, "value2");
|
||||
|
||||
assertEquals("2-value2", returnValue);
|
||||
}
|
||||
|
||||
private InvocableHandlerMethod invocableHandlerMethod(String methodName, Class<?>... paramTypes)
|
||||
throws Exception {
|
||||
Method method = Handler.class.getDeclaredMethod(methodName, paramTypes);
|
||||
InvocableHandlerMethod handlerMethod = new InvocableHandlerMethod(new Handler(), method);
|
||||
handlerMethod.setHandlerMethodArgumentResolvers(argumentResolvers);
|
||||
return handlerMethod;
|
||||
@Test
|
||||
public void exceptionInResolvingArg() throws Exception {
|
||||
HandlerMethodArgumentResolverComposite composite = new HandlerMethodArgumentResolverComposite();
|
||||
composite.addResolver(new ExceptionRaisingArgumentResolver());
|
||||
handleMethod.setHandlerMethodArgumentResolvers(composite);
|
||||
|
||||
try {
|
||||
handleMethod.invokeForRequest(webRequest, null);
|
||||
fail("Expected exception");
|
||||
} catch (HttpMessageNotReadableException ex) {
|
||||
// Expected..
|
||||
// Allow HandlerMethodArgumentResolver exceptions to propagate..
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void illegalArgumentException() throws Exception {
|
||||
StubArgumentResolver intResolver = new StubArgumentResolver(Integer.class, "__invalid__");
|
||||
StubArgumentResolver stringResolver = new StubArgumentResolver(String.class, "value");
|
||||
|
||||
HandlerMethodArgumentResolverComposite composite = new HandlerMethodArgumentResolverComposite();
|
||||
composite.addResolver(intResolver);
|
||||
composite.addResolver(stringResolver);
|
||||
handleMethod.setHandlerMethodArgumentResolvers(composite);
|
||||
|
||||
try {
|
||||
handleMethod.invokeForRequest(webRequest, null);
|
||||
fail("Expected exception");
|
||||
} catch (IllegalArgumentException ex) {
|
||||
assertNotNull("Exception not wrapped", ex.getCause());
|
||||
assertTrue(ex.getCause() instanceof IllegalArgumentException);
|
||||
assertTrue(ex.getMessage().contains("Controller ["));
|
||||
assertTrue(ex.getMessage().contains("Method ["));
|
||||
assertTrue(ex.getMessage().contains("Resolved arguments: "));
|
||||
assertTrue(ex.getMessage().contains("[0] [type=java.lang.String] [value=__invalid__]"));
|
||||
assertTrue(ex.getMessage().contains("[1] [type=java.lang.String] [value=value"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invocationTargetException() throws Exception {
|
||||
Throwable expected = new RuntimeException("error");
|
||||
try {
|
||||
invokeExceptionRaisingHandler(expected);
|
||||
} catch (RuntimeException actual) {
|
||||
assertSame(expected, actual);
|
||||
}
|
||||
|
||||
expected = new Error("error");
|
||||
try {
|
||||
invokeExceptionRaisingHandler(expected);
|
||||
} catch (Error actual) {
|
||||
assertSame(expected, actual);
|
||||
}
|
||||
|
||||
expected = new Exception("error");
|
||||
try {
|
||||
invokeExceptionRaisingHandler(expected);
|
||||
} catch (Exception actual) {
|
||||
assertSame(expected, actual);
|
||||
}
|
||||
|
||||
expected = new Throwable("error");
|
||||
try {
|
||||
invokeExceptionRaisingHandler(expected);
|
||||
} catch (IllegalStateException actual) {
|
||||
assertNotNull(actual.getCause());
|
||||
assertSame(expected, actual.getCause());
|
||||
assertTrue(actual.getMessage().contains("Failed to invoke controller method"));
|
||||
}
|
||||
}
|
||||
|
||||
private void invokeExceptionRaisingHandler(Throwable expected) throws Exception {
|
||||
Method method = ExceptionRaisingHandler.class.getDeclaredMethod("raiseException");
|
||||
Object handler = new ExceptionRaisingHandler(expected);
|
||||
new InvocableHandlerMethod(handler, method).invokeForRequest(webRequest, null);
|
||||
fail("Expected exception");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class Handler {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public String handle(Integer intArg, String stringArg) {
|
||||
return intArg + "-" + stringArg;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@RequestMapping
|
||||
public void parameterNameDiscovery(Integer intArg) {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class ExceptionRaisingHandler {
|
||||
|
||||
private final Throwable t;
|
||||
|
||||
public ExceptionRaisingHandler(Throwable t) {
|
||||
this.t = t;
|
||||
}
|
||||
|
||||
public void raiseException() throws Throwable {
|
||||
throw t;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class ExceptionRaisingArgumentResolver implements HandlerMethodArgumentResolver {
|
||||
|
||||
public boolean supportsParameter(MethodParameter parameter) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
|
||||
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
|
||||
throw new HttpMessageNotReadableException("oops, can't read");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,7 +24,8 @@ import org.springframework.web.bind.support.WebDataBinderFactory;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
|
||||
/**
|
||||
* Resolves a method argument using a stub value and records resolved parameters.
|
||||
* Supports parameters of a given type and resolves them using a stub value.
|
||||
* Also records the resolved parameter value.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
@@ -36,8 +37,8 @@ public class StubArgumentResolver implements HandlerMethodArgumentResolver {
|
||||
|
||||
private List<MethodParameter> resolvedParameters = new ArrayList<MethodParameter>();
|
||||
|
||||
public StubArgumentResolver(Class<?> parameterType, Object stubValue) {
|
||||
this.parameterType = parameterType;
|
||||
public StubArgumentResolver(Class<?> supportedParameterType, Object stubValue) {
|
||||
this.parameterType = supportedParameterType;
|
||||
this.stubValue = stubValue;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user