Using Spring @ResponseStatus to Set HTTP Status Code

Spread the love

Introduction

In Spring, there are many ways in which we can set the Status of the HTTPResponse. In this tutorial, we will achieve this using Spring ResponseStatus annotation.

We can use @ResponseStatus annotation to mark a method or an Exception class with a Status code and reason to be returned. On invoking the marked handler method or when a specified exception is thrown, the HTTP status will be set to the one defined using @ResponseStatus annotation.

With Controller Method

When the method is executed in Spring successfully, Spring provided an HTTP status code 200 (OK) response.

What if we want to return another type of HttpStatus from one of our controller methods?

If we want to specify the response status of a controller method, we need to annotate that method with the @ResponseStatus annotation. It has two interchangeable arguments for the desired response type: code and value.

For Example :

@RestController
@RequestMapping("/api")
public class EmployeeController {

    @Autowired
    private EmployeeRepository employeeRepository;

    @PostMapping(value = "/employee")
    @ResponseStatus(HttpStatus.CREATED)
    public Employee createEmployee(@RequestBody Employee employee)
    {
        return  employeeRepository.save(employee);
    }
}

We can specify the reason for the Response Status also. If we want to signal an error message or success message with reason then we can use this as below. (Implementing the same code with reason value)

@RestController
@RequestMapping("/api")
public class EmployeeController {

    @Autowired
    private EmployeeRepository employeeRepository;

    @PostMapping(value = "/employee")
    @ResponseStatus(value = HttpStatus.CREATED, reason = "Employee Created")
    public Employee createEmployee(@RequestBody Employee employee)
    {
        return  employeeRepository.save(employee);
    }
}

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

Optionally, we can annotate the Controller class with the @ReponseStatus annotation. In this scenario, ResponseStatus configured will be applied to all the request handler methods.

With Error Handlers

We can use the @ResponseStatus annotation with the error handlers the same way we used for the Controller methods.

@ControllerAdvice
public class CustomExceptionHandler extends RuntimeException{

    @ResponseStatus(HttpStatus.NOT_FOUND)
    @ExceptionHandler(NullPointerException.class)
    public void handleException(String message)
    {
        System.out.println(message);
    }
}

When Spring catches this Exception, it used the configuration provided in the @ResponseBody.

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.

The code Example is available on Github

Click here to know more on Spring Framework.