SPR-6009 - @ExceptionHandler methods are still expected to return a ModelAndView, even when consuming a ServletResponse/OutputStream/Writer

This commit is contained in:
Arjen Poutsma 2009-08-19 11:03:28 +00:00
parent 3b7691d525
commit 8d7d3cff1b
2 changed files with 29 additions and 9 deletions

View File

@ -97,7 +97,7 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
logger.debug("Invoking request handler method: " + handlerMethod); logger.debug("Invoking request handler method: " + handlerMethod);
} }
Object retVal = doInvokeMethod(handlerMethod, handler, args); Object retVal = doInvokeMethod(handlerMethod, handler, args);
return getModelAndView(handlerMethod, handler.getClass(), retVal, webRequest); return getModelAndView(handlerMethod, retVal, webRequest);
} }
catch (Exception invocationEx) { catch (Exception invocationEx) {
logger.error("Invoking request method resulted in exception : " + handlerMethod, invocationEx); logger.error("Invoking request method resulted in exception : " + handlerMethod, invocationEx);
@ -324,10 +324,8 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private ModelAndView getModelAndView(Method handlerMethod, private ModelAndView getModelAndView(Method handlerMethod, Object returnValue, ServletWebRequest webRequest)
Class handlerType, throws Exception {
Object returnValue,
ServletWebRequest webRequest) throws Exception {
if (handlerMethod.isAnnotationPresent(ResponseStatus.class)) { if (handlerMethod.isAnnotationPresent(ResponseStatus.class)) {
ResponseStatus responseStatus = handlerMethod.getAnnotation(ResponseStatus.class); ResponseStatus responseStatus = handlerMethod.getAnnotation(ResponseStatus.class);
@ -350,7 +348,7 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
return new ModelAndView((String) returnValue); return new ModelAndView((String) returnValue);
} }
else if (returnValue == null) { else if (returnValue == null) {
return null; return new ModelAndView();
} }
else { else {
throw new IllegalArgumentException("Invalid handler method return value: " + returnValue); throw new IllegalArgumentException("Invalid handler method return value: " + returnValue);

View File

@ -17,6 +17,8 @@
package org.springframework.web.servlet.mvc.annotation; package org.springframework.web.servlet.mvc.annotation;
import java.io.IOException; import java.io.IOException;
import java.io.Writer;
import java.io.UnsupportedEncodingException;
import java.net.BindException; import java.net.BindException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
@ -25,6 +27,7 @@ import static org.junit.Assert.*;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.springframework.http.HttpStatus;
import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
@ -32,9 +35,10 @@ import org.springframework.util.ClassUtils;
import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.ModelAndView;
import org.springframework.http.HttpStatus;
/** @author Arjen Poutsma */ /**
* @author Arjen Poutsma
*/
public class AnnotationMethodHandlerExceptionResolverTests { public class AnnotationMethodHandlerExceptionResolverTests {
private AnnotationMethodHandlerExceptionResolver exceptionResolver; private AnnotationMethodHandlerExceptionResolver exceptionResolver;
@ -59,7 +63,6 @@ public class AnnotationMethodHandlerExceptionResolverTests {
assertNotNull("No ModelAndView returned", mav); assertNotNull("No ModelAndView returned", mav);
assertEquals("Invalid view name returned", "BindException", mav.getViewName()); assertEquals("Invalid view name returned", "BindException", mav.getViewName());
assertEquals("Invalid status code returned", 406, response.getStatus()); assertEquals("Invalid status code returned", 406, response.getStatus());
} }
@Test(expected = IllegalStateException.class) @Test(expected = IllegalStateException.class)
@ -69,6 +72,16 @@ public class AnnotationMethodHandlerExceptionResolverTests {
exceptionResolver.resolveException(request, response, controller, ex); exceptionResolver.resolveException(request, response, controller, ex);
} }
@Test
public void noModelAndView() throws UnsupportedEncodingException {
IllegalArgumentException ex = new IllegalArgumentException();
NoMAVReturningController controller = new NoMAVReturningController();
ModelAndView mav = exceptionResolver.resolveException(request, response, controller, ex);
assertNotNull("No ModelAndView returned", mav);
assertTrue("ModelAndView not empty", mav.isEmpty());
assertEquals("Invalid response written", "IllegalArgumentException", response.getContentAsString());
}
@Controller @Controller
private static class SimpleController { private static class SimpleController {
@ -105,4 +118,13 @@ public class AnnotationMethodHandlerExceptionResolverTests {
} }
} }
@Controller
private static class NoMAVReturningController {
@ExceptionHandler(Exception.class)
public void handle(Exception ex, Writer writer) throws IOException {
writer.write(ClassUtils.getShortName(ex.getClass()));
}
}
} }