β¬ οΈ Back to Controller Index
Request/Response Lifecycle
The complete flow of an HTTP request through the Controller Layer.
Complete Request Flow
Hereβs how a typical request (creating a supplier) flows through all layers:
1. HTTP Request arrives at Spring DispatcherServlet
POST /api/suppliers
Content-Type: application/json
Authorization: Bearer <token>
{ "name": "ACME Corp", ... }
β
2. Request routing matches URL pattern to controller method
DispatcherServlet identifies SupplierController.create()
β
3. Spring Security checks @PreAuthorize annotation
@PreAuthorize("hasRole('ADMIN')")
ββ If not authorized β AccessDeniedException β 403 Forbidden
ββ If authorized β Continue
β
4. @Valid triggers DTO field validation
Validates CreateSupplierDTO fields
ββ @NotBlank on name field
ββ @Email on contactEmail field
ββ All constraints checked
β
If validation fails:
ββ MethodArgumentNotValidException thrown
ββ GlobalExceptionHandler catches
ββ Returns 400 Bad Request
β
5. Jackson deserializes request body JSON β DTO
{ "name": "ACME Corp", ... }
β
CreateSupplierDTO object (fully populated)
β
6. Controller method executes
supplierService.create(dto)
β
7. Service layer executes
- Service validator checks business rules
- Service calls repository
- Repository persists to database
- Service returns DTO
β
If exception in service:
ββ Service throws exception
ββ GlobalExceptionHandler catches
ββ Returns 4xx or 5xx error
β
8. Controller receives SupplierDTO from service
Has: id, name, contactName, etc.
β
9. Jackson serializes DTO β JSON response body
SupplierDTO object
β
{ "id": "abc123", "name": "ACME Corp", ... }
β
10. Controller builds ResponseEntity with status code
ResponseEntity.created(location).body(created)
ββ Status: 201 CREATED
ββ Location header: /api/suppliers/abc123
ββ Body: Serialized DTO
β
11. HTTP Response returned to client
HTTP/1.1 201 Created
Location: /api/suppliers/abc123
Content-Type: application/json
{ "id": "abc123", "name": "ACME Corp", ... }
Request Validation Checkpoint
Request JSON received
β
DispatcherServlet routes to controller
β
Spring Security @PreAuthorize check
ββ Not authenticated? β 401 Unauthorized
ββ Not authorized? β 403 Forbidden
ββ Authorized? β Continue
β
Jackson deserializes JSON β DTO
β
@Valid annotation triggers field validation
ββ Any constraint violations? β 400 Bad Request
ββ All valid? β Continue
β
Controller method invoked
Response Path
Service returns domain DTO
β
Controller wraps in ResponseEntity
ββ Set status code (200, 201, 204, etc.)
ββ Add headers if needed (Location, etc.)
ββ Add body if applicable
β
Jackson serializes DTO β JSON
β
HTTP Response to client
ββ Status line
ββ Headers
ββ JSON body
Error Handling Path
Any layer throws exception
β
Exception propagates up to GlobalExceptionHandler
β
Handler identifies exception type
ββ IllegalArgumentException β 400 Bad Request
ββ NoSuchElementException β 404 Not Found
ββ IllegalStateException β 409 Conflict
ββ AccessDeniedException β 403 Forbidden
ββ Generic Exception β 500 Internal Server Error
β
Handler builds ErrorResponse object
ββ Code: error type (BAD_REQUEST, NOT_FOUND, etc.)
ββ Message: human-readable explanation
ββ Path: request URL
ββ Timestamp: when error occurred
β
Jackson serializes ErrorResponse β JSON
β
HTTP Error Response to client
ββ Appropriate status code (400, 404, 409, etc.)
ββ JSON body with error details