跪拜 Guibai
← All articles
Frontend · Backend · Full-Stack

How a Spring Boot Controller Catches an HTTP Request and Turns It into Java Objects

By swipe ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

A frontend developer transitioning to full-stack work stops being just an API consumer and starts defining the contract. Understanding this request pipeline prevents the most common backend bugs: 404s from mismatched paths, silent data corruption from missing validation, and brittle frontends that parse human-readable error messages instead of stable business codes.

Summary

Spring Boot's `@RestController` and mapping annotations route an incoming HTTP request to the correct Java method. Query parameters, path variables, and JSON bodies are bound to Request DTOs, which act as a strict whitelist for external input. `@Valid` triggers Jakarta Bean Validation before the Controller method executes, catching invalid data early and returning structured 400 errors via a global exception handler.

A clear separation exists between Request DTOs (input whitelist), Response DTOs (output contract), and database Entities (table mapping). Mixing them leads to security holes and brittle APIs. The project wraps every response in an `ApiResponse<T>` envelope containing a stable business code, a human-readable message, a trace ID for debugging, and a timestamp, ensuring the frontend always receives a predictable structure.

HTTP semantics are respected: a successful creation returns 201, validation failures return 400, and unknown errors return 500. A `GlobalExceptionHandler` catches everything from malformed JSON to business exceptions, preventing stack traces from leaking to the client. The full request chain—from path matching to parameter binding to validation to response wrapping—is a pipeline where failures can occur before the Controller method is ever called.

Takeaways
Class-level `@RequestMapping` and method-level `@GetMapping`/`@PostMapping` combine to form the full URL path; forgetting the class prefix is a frequent cause of 404s.
GET requests bind query parameters to a Request DTO; POST and PATCH use `@RequestBody` to deserialize JSON into a Java object.
`@PathVariable` extracts dynamic segments like `{id}` from the URL and converts them to the declared Java type.
`@Valid` triggers Jakarta Bean Validation annotations on the Request DTO, rejecting bad input before the Controller method runs.
Request DTOs are an input whitelist—fields like `id`, `createdBy`, and `createdAt` must never be settable by the caller.
Response DTOs are an output contract that can assemble data from multiple tables, such as including a category name alongside a category ID.
`ApiResponse<T>` wraps every response with a stable `code` for programmatic checks, a `traceId` for log correlation, and a `timestamp` in UTC.
`ResponseEntity` gives fine-grained control over HTTP status codes, such as returning 201 Created instead of 200 OK.
`GlobalExceptionHandler` converts Java exceptions into structured JSON errors, ensuring stack traces never leak to the client.
Frontend validation is a UX convenience; backend validation is a security boundary that cannot be bypassed.
Conclusions

Many 404 errors in Spring Boot are not routing bugs but a failure to mentally combine the class-level and method-level path mappings.

Using a single DTO for both input and output, or exposing database Entities directly, is the fastest way to create privilege-escalation vulnerabilities and brittle contracts.

The `traceId` field in `ApiResponse` is an underappreciated debugging tool: it lets a frontend developer paste an ID to the backend team instead of describing a vague error.

Returning HTTP 200 for every response, including errors, cripples monitoring and load-balancer health checks; distinct status codes are operational infrastructure, not pedantry.

Parameter validation failures happen before the Controller method body executes, which means a breakpoint on the first line of the method will never be hit for a bad request.

Concepts & terms
Controller
The Web layer entry point in Spring MVC. It handles HTTP concerns—routing, parameter binding, validation, and response wrapping—and delegates business logic to a Facade or Service.
@RestController
A Spring annotation marking a class as a REST API Controller. It combines `@Controller` and `@ResponseBody`, meaning method return values are serialized directly to JSON instead of resolving to a view template.
Request DTO
A Data Transfer Object that defines the whitelist of fields an external caller is allowed to submit for a specific operation. It carries validation annotations and must exclude server-generated fields like IDs and timestamps.
Response DTO
A Data Transfer Object that defines the stable output contract for an API. It can assemble data from multiple sources and should only include fields the frontend actually needs.
ApiResponse<T>
A generic response envelope used uniformly across all business APIs. It contains a stable business code (`code`), a human-readable message, the payload (`data`), a trace ID for log correlation, and a UTC timestamp.
Bean Validation
A Java specification (Jakarta Validation) that lets you declare constraints like `@NotNull`, `@Size`, or `@Positive` directly on DTO fields. Spring triggers validation when `@Valid` is present on a Controller parameter.
GlobalExceptionHandler
A class annotated with `@RestControllerAdvice` that intercepts exceptions thrown anywhere in the Controller layer and converts them into a consistent `ApiResponse` structure with the appropriate HTTP status code.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗