Reading JSON Input with @RequestBody
When a client sends a POST or PUT request with a JSON payload, Spring Boot uses the @RequestBody annotation on a method parameter to deserialize that payload into a Java object. Behind the scenes, an HttpMessageConverter (Jackson's MappingJackson2HttpMessageConverter by default) reads the request's Content-Type header, confirms it matches application/json, and maps each JSON field to a matching property on the target class via getters/setters or a constructor.
Cricket analogy: It's like a scorer translating a raw ball-by-ball radio commentary into a structured scorecard entry — @RequestBody takes raw JSON text and maps it onto a structured Java object.
Writing JSON Output with @ResponseBody
On the way out, @ResponseBody (implicit in every method when using @RestController) tells Spring to serialize the returned Java object back into JSON using the same Jackson converter, rather than resolving it as a logical view name. Field visibility, naming strategy, and null handling during this serialization are all controlled by Jackson annotations (@JsonProperty, @JsonIgnore) or global configuration in application.properties, such as spring.jackson.default-property-inclusion=non_null.
Cricket analogy: Like a scorer converting the structured scorecard back into a spoken commentary line for the broadcast — @ResponseBody turns the Java object back into a JSON 'broadcast' for the client.
public record CreateOrderRequest(
@NotNull Long customerId,
@NotEmpty List<OrderLineDto> lines) {}
@RestController
@RequestMapping("/api/orders")
public class OrderController {
@PostMapping
public ResponseEntity<OrderDto> createOrder(
@RequestBody @Valid CreateOrderRequest request) {
OrderDto created = orderService.create(request);
URI location = URI.create("/api/orders/" + created.id());
return ResponseEntity.created(location).body(created);
}
}DTOs vs Domain Entities in Request/Response Shapes
Using dedicated request and response DTOs (as records or plain classes) instead of exposing JPA entities directly decouples your public API contract from your internal database schema. This means you can rename a database column, restructure a relationship, or add an internal-only field to an entity without breaking API consumers, as long as the DTO mapping layer absorbs the change. It also lets you tailor exactly which fields are writable on input (a request DTO might omit an 'id' field) versus which fields are exposed on output.
Cricket analogy: Like a player's public stats card shown to fans (curated DTO) versus the team's full internal fitness and injury database (entity) — fans only ever see the curated view.
Java records are an excellent fit for immutable request/response DTOs: they auto-generate constructors, accessors, equals/hashCode, and toString, and Jackson supports deserializing directly into records without extra configuration since Jackson 2.12+.
Watch out for over-posting: if a request DTO exposes a settable 'role' or 'isAdmin' field that maps straight onto an entity, a malicious client could escalate privileges by including that field in the JSON body. Keep request DTOs minimal and only accept fields the endpoint is meant to change.
- @RequestBody deserializes an incoming JSON payload into a Java object via an HttpMessageConverter.
- @ResponseBody (implicit under @RestController) serializes the returned object back into JSON.
- Jackson is Spring Boot's default JSON library, configurable via annotations or application.properties.
- Dedicated request/response DTOs decouple the public API contract from internal domain entities.
- Java records are a concise, immutable fit for defining request and response DTOs.
- Never let a request DTO map directly onto sensitive entity fields to avoid over-posting vulnerabilities.
- ResponseEntity.created(location).body(dto) is the idiomatic way to return a 201 Created response with a Location header.
Practice what you learned
1. What library does Spring Boot use by default to convert JSON to Java objects and back?
2. What is the risk of over-posting in a request DTO?
3. Why are Java records well suited for request/response DTOs?
4. What does ResponseEntity.created(location).body(dto) produce?
5. Why should you avoid returning JPA entities directly and instead use response DTOs?
Was this page helpful?
You May Also Like
Building REST Controllers
Learn how to build REST controllers in Spring Boot using @RestController, structure methods cleanly, and return well-formed HTTP responses.
Validation in Spring Boot
Learn how to validate incoming request data in Spring Boot using Bean Validation annotations, @Valid, and custom validators.
Exception Handling in Spring Boot
Learn how to handle errors gracefully in Spring Boot REST APIs using @ExceptionHandler, @ControllerAdvice, and structured error responses.
Related Reading
Related Study Notes in Web Development
Browse all study notesWebSockets Study Notes
Web Development · 30 topics
Web DevelopmentWebAssembly Study Notes
WebAssembly · 30 topics
Web DevelopmentgRPC Study Notes
Protocol Buffers · 30 topics
Web DevelopmentFlask Study Notes
Python · 30 topics
Web DevelopmentDjango Study Notes
Python · 30 topics
Web DevelopmentNext.js Study Notes
JavaScript · 30 topics