100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Java

Request and Response Bodies

Learn how Spring Boot serializes and deserializes JSON request and response bodies using @RequestBody, @ResponseBody, and Jackson.

Web LayerBeginner9 min readJul 10, 2026
Analogies

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.

java
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

Was this page helpful?

Topics covered

#Java#SpringBootStudyNotes#WebDevelopment#RequestAndResponseBodies#Request#Response#Bodies#Reading#StudyNotes#SkillVeris