@ResponseStatus in Spring — Custom HTTP Status Codes
Fast recall
Quick revision
Core answer
Understanding of HTTP status code control mechanisms in Spring REST and how to signal different outcomes to API clients.
Always using ResponseEntity for status code control when @ResponseStatus provides a simpler, more declarative approach for common cases.
Demonstrate @ResponseStatus on exception classes to show automatic exception-to-HTTP-status mapping, which is a cleaner pattern than manually catching exceptions in every controller method.
Interview-ready guide
Interview answer
For example, @ResponseStatus(HttpStatus.NO_CONTENT) on a successful void delete method fixes its normal status at 204. An OrderNotFoundException annotated NOT_FOUND can become 404 when it escapes a controller request. If one method returns either 200 with a body or 404, ResponseEntity or exception handling expresses that branch more clearly.
@ResponseStatus in Spring — Custom HTTP Status Codes
Direct Answer
@ResponseStatus associates a fixed HTTP status and optional reason with a controller method or exception type. A method annotation suits a response whose success status is constant. An exception annotation can be resolved when that exception reaches Spring MVC's exception handling. It does not turn failures thrown anywhere in the application, such as a swallowed scheduler exception, into an HTTP response.
Code Example
@ResponseStatus(HttpStatus.NOT_FOUND) // Maps exception to 404 everywhere
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException(String message) {
super(message);
}
}
@RestController
@RequestMapping("/api/orders")
public class OrderController {
private final OrderRepository orderRepository;
public OrderController(OrderRepository orderRepository) {
this.orderRepository = orderRepository;
}
@PostMapping
@ResponseStatus(HttpStatus.CREATED) // Returns 201 instead of default 200
public Order createOrder(@RequestBody Order order) {
return orderRepository.save(order);
}
@GetMapping("/{id}")
public Order getOrder(@PathVariable Long id) {
return orderRepository.findById(id)
.orElseThrow(() -> new ResourceNotFoundException("Order not found")); // Automatic 404 response
}
@DeleteMapping("/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT) // Returns 204, signals successful deletion with no body
public void deleteOrder(@PathVariable Long id) {
orderRepository.deleteById(id);
}
}
Common Mistakes & Pitfalls
- Overusing ResponseEntity: Freshers learn ResponseEntity first and use it everywhere, even when at-ResponseStatus would be simpler. If the status code is always 201 for a POST method, at-ResponseStatus is more readable than ResponseEntity.status(HttpStatus.CREATED).body(order).
- Forgetting on exceptions: Not annotating custom exceptions, then manually catching them in every controller to return the right status. Mark the exception class once with at-ResponseStatus(HttpStatus.NOT_FOUND) and Spring handles it globally.
- Mixing approaches inconsistently: Using at-ResponseStatus on some methods and ResponseEntity on others for the same status code, creating inconsistent patterns. Pick one approach per use case.
- Not understanding precedence: If both at-ResponseStatus and ResponseEntity are present, ResponseEntity wins. The annotation is ignored when you explicitly return ResponseEntity, which can confuse debugging.
Check your understanding
Answer these without looking back at the article.
- What is the difference between @ResponseStatus and ResponseEntity?
- How do you return 201 Created from a POST endpoint?
- When would you use @ResponseStatus on an exception class vs @ExceptionHandler?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.