1. Introduction

In Spring MVC, we have many ways to set the status code of an HTTP response.

In this short tutorial, we will see the most straightforward way: using the @ResponseStatus annotation.

2. On Controller Methods

When an endpoint returns successfully, Spring provides an HTTP 200 (OK) response.

If we want to specify the response status of a controller method, we can mark that method with @ResponseStatus. It has two interchangeable arguments for the desired response status: code, and value. For example, we can indicate that the server refuses to brew coffee because it is a teapot:

@ResponseStatus(HttpStatus.I_AM_A_TEAPOT)
void teaPot() {}

When we want to signal an error, we can provide an error message via the reason argument:

@ResponseStatus(HttpStatus.BAD_REQUEST, reason = "Some parameters are invalid")
void onIllegalArgumentException(IllegalArgumentException exception) {}

Note, that when we set reason, Spring calls HttpServletResponse.sendError(). Therefore, it will send an HTML error page to the client, which makes it a bad fit for REST endpoints.

Also note, that Spring only uses @ResponseStatus, when the marked method completes successfully (without throwing an Exception).

3. With Error Handlers

We have three ways to use @ResponseStatus to convert an Exception to an HTTP response status:

  • using @ExceptionHandler
  • using @ControllerAdvice
  • marking the Exception class

In order to use the first two solutions, we have to define an error handler method. You can read more about this topic in this article.

We can use @ResponseStatus with these error handler methods the same way we did with regular MVC methods in the previous section.

When we don’t need dynamic error responses, the most straightforward solution is the third one: marking the Exception class with @ResponseStatus:

@ResponseStatus(code = HttpStatus.BAD_REQUEST)
class CustomException extends RuntimeException {}

When Spring catches this Exception, it uses the settings we provided in @ResponseStatus.

Note, that when we mark an Exception class with @ResponseStatus, Spring always calls HttpServletResponse.sendError()**, whether we set reason or not.

Also note, that Spring uses the same configuration for subclasses, unless we mark them with @ResponseStatus, too.

4. Conclusion

In this article, we saw how we can use @ResponseStatus to set HTTP response code in different scenarios, including error handling.

As usual, the examples are available over on GitHub.