Does anybody know why I cannot use @ResponseStatus(reason = "My message")
on an exception handler in spring MVC while still returning a @ResponseBody. What seems to happen is that if I use the reason
attribute
// this exception handle works, the result is a 404 and the http body is the json serialised
// {"message", "the message"}
@ExceptionHandler
@ResponseStatus(value = HttpStatus.NOT_FOUND)
public Map<String, String> notFoundHandler(NotFoundException e){
return Collections.singletonMap("message", e.getMessage());
}
// this doesn't... the response is a 404 and the status line reads 'Really really not found'
// but the body is actually the standard Tomcat 404 page
@ExceptionHandler
@ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "Really really not found")
public Map<String, String> reallyNotFoundHandler(ReallyNotFoundException e){
return Collections.singletonMap("message", e.getMessage());
}
The code for this example is over on github.
Spring MVC Framework provides following ways to help us achieving robust exception handling. Controller Based - We can define exception handler methods in our controller classes. All we need is to annotate these methods with @ExceptionHandler annotation. This annotation takes Exception class as argument.
@ControllerAdvice constructor comes with some special arguments which allows you to scan only the related portion of your application and handle only those exceptions thrown by the respective classes mentioned in the constructor. By default it will scan and handle all the classes in your application.
Spring MVC provides exception handling for your web application to make sure you are sending your own exception page instead of the server-generated exception to the user. The @ExceptionHandler annotation is used to detect certain runtime exceptions and send responses according to the exception.
It seems that this is a direct result of the following code from AnnotationMethodHandlerExceptionResolver
private ModelAndView getModelAndView(Method handlerMethod, Object returnValue, ServletWebRequest webRequest)
throws Exception {
ResponseStatus responseStatusAnn = AnnotationUtils.findAnnotation(handlerMethod, ResponseStatus.class);
if (responseStatusAnn != null) {
HttpStatus responseStatus = responseStatusAnn.value();
String reason = responseStatusAnn.reason();
if (!StringUtils.hasText(reason)) {
// this doesn't commit the response
webRequest.getResponse().setStatus(responseStatus.value());
}
else {
// this commits the response such that any more calls to write to the
// response are ignored
webRequest.getResponse().sendError(responseStatus.value(), reason);
}
}
/// snip
}
This has been reported to Springsource in SPR-8251:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With