Spring MVC - Using @ResponseStatus on Exception classes

[Updated: Feb 8, 2017, Created: Jan 19, 2017]

The exception classes which we create for our application, can be annotated with @ResponseStatus. In that case an unhandled exception returned to the client will have the specified HTTP status code.

If such exception is wrapped in another exception, then the status code will still be send in the response because the underlying exception resolver looks recursively for @ResponseStatus present on cause exceptions (starting Spring 4.2)

This feature is implemented in ResponseStatusExceptionResolver (another implementation of HandlerExceptionResolver). By default an instance of this resolver is initialized with DispatcherServlet, so we don't have to do any related configuration to use it.


Example

Using @ResponseStatus on an exception class

@ResponseStatus(HttpStatus.FORBIDDEN)
public class UserNotLoggedInException extends Exception {

    public UserNotLoggedInException (String message) {
        super(message);
    }
}

A controller handler throwing the exception

package com.logicbig.example;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;

@Controller
public class ExampleController {

    @RequestMapping("/admin")
    @ResponseBody
    public String handleRequest (HttpServletRequest request)
              throws UserNotLoggedInException {

        Object user = request.getSession()
                             .getAttribute("user");
        if (user == null) {
            throw new UserNotLoggedInException("user: " + user);
        }
        return "test response " + user;
    }

    //nested exceptions
    @RequestMapping("/test")
    public void handleRequest2 () throws Exception {
        throw new Exception(new UserNotLoggedInException(null));
    }
}

The exception thrown should not be handled by code or by other exception resolvers, for example it shouldn't be handled by @ExceptionHandler, because that will override the status code specified by the exception class's @ResponseStatus.


Running the embedded tomcat server

mvn clean tomcat7:run-war

Output

/admin


/test

In this case, we wrapped UserNotLoggedInException inside java.lang.Exception instance.


Without @ResponseStatus on the exception class:

If we remove @ResponseStatus from UserNotLoggedInException.java then:

Normally any unhandled exception thrown will return an HTTP 500 response (Internal Server Error).

Other uses of @ResponseStatus

  1. It is used on the controller's handler methods, i.e. along with @RequestMapping. It can also be used on @Controller class level, in that case it is inherited by all methods.
  2. It is used on the exception handler methods, i.e. along with @ExceptionHandler




Example Project

Dependencies and Technologies Used :

  • spring-webmvc 4.3.5.RELEASE: Spring Web MVC.
  • javax.servlet-api 3.0.1 Java Servlet API
  • JDK 1.8
  • Maven 3.3.9

Response Status On Exceptions Select All Download
  • exception-type-response-status
    • src
      • main
        • java
          • com
            • logicbig
              • example

See Also