Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring MVC: using @ResponseStatus(reason = '') on a @ResponseBody exception handler in tomcat

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.

like image 262
Gareth Davis Avatar asked Apr 12 '11 15:04

Gareth Davis


People also ask

How do you handle authentication and exception handling in Spring Boot and Spring MVC applications?

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.

What is special argument for @ControllerAdvice constructor which make sure to scan and handle the exceptions from the mentioned classes?

@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.

Which of the following annotations are provided by Spring MVC for handling exceptions?

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.


1 Answers

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:

like image 77
Gareth Davis Avatar answered Sep 26 '22 07:09

Gareth Davis