0
0
Spring Bootframework~15 mins

Returning different status codes in Spring Boot - Deep Dive

Choose your learning style9 modes available
Overview - Returning different status codes
What is it?
Returning different status codes means sending specific numbers from a web server to a client to show what happened with their request. These codes tell if the request was successful, if there was an error, or if something else happened. In Spring Boot, you can control these codes easily when building web applications. This helps clients understand the result without reading the full message.
Why it matters
Without returning the right status codes, clients like browsers or apps would not know if their request worked or failed, leading to confusion or wrong behavior. For example, if a client sends data to save but the server does not say if it succeeded or failed, the client might try again or show wrong info. Returning correct status codes makes communication clear and reliable between servers and clients.
Where it fits
Before learning this, you should know basic Spring Boot controllers and how to handle HTTP requests. After this, you can learn about exception handling in Spring Boot and building REST APIs that follow best practices for communication.
Mental Model
Core Idea
HTTP status codes are simple signals from the server that tell the client what happened with their request.
Think of it like...
It's like traffic lights for cars: green means go (success), yellow means caution (warning), and red means stop (error). The server uses status codes to guide the client on what to do next.
┌───────────────┐
│ Client sends  │
│ HTTP request  │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Server handles │
│ the request   │
└──────┬────────┘
       │
       ▼
┌─────────────────────────────┐
│ Server sends HTTP status code│
│ (e.g., 200, 404, 500)        │
└──────────────┬──────────────┘
               │
               ▼
┌─────────────────────────────┐
│ Client reads status code and │
│ acts accordingly             │
└─────────────────────────────┘
Build-Up - 7 Steps
1
FoundationBasics of HTTP status codes
🤔
Concept: Learn what HTTP status codes are and their main categories.
HTTP status codes are three-digit numbers sent by servers to clients. They fall into groups: 1xx (informational), 2xx (success), 3xx (redirection), 4xx (client errors), and 5xx (server errors). For example, 200 means OK, 404 means Not Found, and 500 means Internal Server Error.
Result
You understand the meaning of common HTTP status codes and their categories.
Knowing the categories helps you quickly guess what happened just by looking at the code.
2
FoundationSpring Boot controller basics
🤔
Concept: Understand how to create a simple controller that handles HTTP requests.
In Spring Boot, you create a controller class with methods annotated by @GetMapping, @PostMapping, etc. These methods run when a client sends a matching HTTP request. By default, Spring returns 200 OK if the method completes without error.
Result
You can write a basic controller that responds to HTTP requests.
Controllers are the starting point to control what the server sends back, including status codes.
3
IntermediateReturning status codes with ResponseEntity
🤔Before reading on: do you think you can set any status code by just returning a string from a controller? Commit to your answer.
Concept: Use ResponseEntity to set both the response body and status code explicitly.
ResponseEntity is a Spring class that lets you build a response with a body, headers, and status code. For example, return ResponseEntity.status(201).body("Created") sends status 201 Created with a message. This is better than default 200 when you want to signal something specific.
Result
You can send different status codes like 201, 404, or 400 from your controller methods.
Understanding ResponseEntity unlocks precise control over HTTP responses, improving client-server communication.
4
IntermediateUsing @ResponseStatus annotation
🤔Before reading on: do you think @ResponseStatus can change status codes for exceptions as well as normal methods? Commit to your answer.
Concept: @ResponseStatus lets you set a fixed status code on a method or exception class.
You can add @ResponseStatus(HttpStatus.NOT_FOUND) on a method or custom exception. When that method runs or exception is thrown, Spring sends the specified status code automatically. This is useful for simple cases without building ResponseEntity manually.
Result
You can mark methods or exceptions to return specific status codes easily.
Knowing @ResponseStatus simplifies code when you want fixed status codes for certain outcomes.
5
IntermediateHandling errors with status codes
🤔Before reading on: do you think Spring Boot returns 500 for all errors by default? Commit to your answer.
Concept: Spring Boot returns 500 Internal Server Error for unhandled exceptions but you can customize this behavior.
By default, if your controller throws an exception not caught, Spring sends 500. You can create @ControllerAdvice classes with @ExceptionHandler methods to catch exceptions and return custom status codes and messages. This improves user experience by giving meaningful errors.
Result
You can control error responses and status codes globally in your app.
Custom error handling prevents generic 500 errors and helps clients understand problems better.
6
AdvancedDynamic status codes based on logic
🤔Before reading on: do you think status codes can be decided at runtime based on data? Commit to your answer.
Concept: You can decide which status code to return dynamically inside controller methods.
Inside a controller method, you can check conditions and return different ResponseEntity with different status codes. For example, if a resource exists, return 200 OK; if not, return 404 Not Found. This makes your API flexible and informative.
Result
Your API can respond with the right status code depending on the situation.
Dynamic status codes make your API smarter and more user-friendly.
7
ExpertStatus codes in reactive Spring WebFlux
🤔Before reading on: do you think setting status codes in reactive programming is the same as in traditional Spring MVC? Commit to your answer.
Concept: In reactive Spring WebFlux, you set status codes using reactive types and response builders differently than in Spring MVC.
WebFlux uses Mono and Flux to handle async data. To set status codes, you use ServerResponse.status(HttpStatus).body(...) or manipulate ServerHttpResponse directly. This requires understanding reactive streams and non-blocking programming.
Result
You can return different status codes correctly in reactive Spring applications.
Mastering status codes in reactive apps is key for modern scalable web services.
Under the Hood
When a Spring Boot controller method finishes, the framework builds an HTTP response. If you return a ResponseEntity, Spring reads its status code and body and sets them in the HTTP response. If you use @ResponseStatus, Spring reads the annotation and sets that code. For exceptions, Spring's DispatcherServlet catches them and looks for handlers or annotations to decide the status code. Finally, the HTTP response with the status code and body is sent over the network to the client.
Why designed this way?
HTTP status codes are part of the HTTP standard to separate status from content. Spring Boot follows this standard to keep compatibility with all HTTP clients. Using ResponseEntity and annotations gives developers flexible ways to control responses without breaking the framework's flow. This design balances ease of use with power and extensibility.
┌───────────────────────────────┐
│ Client sends HTTP request      │
└───────────────┬───────────────┘
                │
                ▼
┌───────────────────────────────┐
│ Spring DispatcherServlet       │
│ routes request to controller   │
└───────────────┬───────────────┘
                │
                ▼
┌───────────────────────────────┐
│ Controller method executes     │
│ returns ResponseEntity or data │
└───────────────┬───────────────┘
                │
                ▼
┌───────────────────────────────┐
│ Spring reads @ResponseStatus or│
│ ResponseEntity status          │
└───────────────┬───────────────┘
                │
                ▼
┌───────────────────────────────┐
│ HTTP response built with status│
│ code and body                 │
└───────────────┬───────────────┘
                │
                ▼
┌───────────────────────────────┐
│ Response sent to client        │
└───────────────────────────────┘
Myth Busters - 4 Common Misconceptions
Quick: do you think returning a string from a controller sets the status code automatically? Commit to yes or no.
Common Belief:Returning a string from a controller method automatically sets the correct status code.
Tap to reveal reality
Reality:Returning a string sets the response body but the status code defaults to 200 OK unless changed explicitly.
Why it matters:If you expect an error code but only return a string, clients will think the request succeeded, causing confusion or bugs.
Quick: do you think @ResponseStatus can change status codes dynamically at runtime? Commit to yes or no.
Common Belief:@ResponseStatus can be used to set different status codes dynamically based on conditions.
Tap to reveal reality
Reality:@ResponseStatus sets a fixed status code at compile time and cannot change dynamically during execution.
Why it matters:Misusing @ResponseStatus for dynamic needs leads to incorrect status codes and harder-to-maintain code.
Quick: do you think Spring Boot always returns 500 for any error? Commit to yes or no.
Common Belief:Spring Boot returns 500 Internal Server Error for all exceptions by default.
Tap to reveal reality
Reality:Spring Boot returns 500 only for unhandled exceptions; handled exceptions can return other codes if configured.
Why it matters:Assuming all errors are 500 prevents developers from customizing meaningful error responses.
Quick: do you think status codes are only useful for browsers? Commit to yes or no.
Common Belief:HTTP status codes only matter for browsers to show error pages.
Tap to reveal reality
Reality:Status codes are essential for all HTTP clients, including mobile apps, APIs, and automated systems, to understand server responses.
Why it matters:Ignoring status codes limits interoperability and can break client applications.
Expert Zone
1
ResponseEntity allows setting headers along with status codes, enabling fine-grained control over HTTP responses beyond just status and body.
2
Using @ControllerAdvice with @ExceptionHandler lets you centralize error handling and status code management, improving maintainability in large apps.
3
In reactive WebFlux, status code setting must consider non-blocking streams, which changes how and when you can set the response compared to traditional MVC.
When NOT to use
Avoid using @ResponseStatus for complex or dynamic status code logic; instead, use ResponseEntity or exception handlers. For reactive applications, do not use traditional MVC response methods; use WebFlux-specific response builders. If you need to handle very custom HTTP behavior, consider filters or interceptors instead of controllers.
Production Patterns
In production, APIs often use ResponseEntity to return 200 for success, 201 for created resources, 400 for bad requests, 404 for missing data, and 500 for server errors. Centralized exception handling with @ControllerAdvice is common to keep controllers clean. Reactive apps use ServerResponse builders to set status codes in a non-blocking way.
Connections
REST API design
Returning correct status codes is a core part of REST API best practices.
Understanding status codes helps design APIs that communicate clearly and follow standards, improving client integration.
HTTP protocol
Status codes are defined by the HTTP protocol standard.
Knowing the protocol basics helps understand why status codes exist and how clients interpret them.
Traffic control systems
Status codes function like signals in traffic control systems to manage flow and safety.
Seeing status codes as signals clarifies their role in guiding client behavior and preventing errors.
Common Pitfalls
#1Returning data without setting status code for errors
Wrong approach:public String getUser(int id) { if (userNotFound) { return "User not found"; } return userData; }
Correct approach:public ResponseEntity getUser(int id) { if (userNotFound) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body("User not found"); } return ResponseEntity.ok(userData); }
Root cause:Returning a string sets only the body, not the status code, so the client always sees 200 OK.
#2Using @ResponseStatus for dynamic status codes
Wrong approach:@ResponseStatus(HttpStatus.NOT_FOUND) public String getUser(int id) { if (userExists) { return "User data"; } else { return "User not found"; } }
Correct approach:public ResponseEntity getUser(int id) { if (userExists) { return ResponseEntity.ok("User data"); } else { return ResponseEntity.status(HttpStatus.NOT_FOUND).body("User not found"); } }
Root cause:@ResponseStatus sets a fixed status code and cannot change based on conditions.
#3Not handling exceptions to set proper status codes
Wrong approach:public String getUser(int id) { User user = userService.findById(id); // throws exception if not found return user.toString(); }
Correct approach:@ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(UserNotFoundException.class) public ResponseEntity handleNotFound() { return ResponseEntity.status(HttpStatus.NOT_FOUND).body("User not found"); } }
Root cause:Without exception handling, Spring returns 500 for exceptions, which may not be accurate.
Key Takeaways
HTTP status codes are essential signals that tell clients what happened with their request.
Spring Boot provides multiple ways to return different status codes, including ResponseEntity and @ResponseStatus.
Using ResponseEntity gives you full control to set status codes dynamically based on your logic.
Proper error handling with custom status codes improves client understanding and user experience.
In reactive Spring WebFlux, setting status codes requires different techniques suited for non-blocking programming.