LearnAI ToolsCareerPractice BuildsPlayContact
Lesson 1419 min read

Request Body & ResponseEntity

Learn how @RequestBody deserializes incoming JSON into Java objects, and how ResponseEntity gives you full control over status codes and headers.

Introduction

So far your controllers have returned plain strings and read simple values from the URL. Real APIs need to accept structured JSON in the request body — think of the payload a client sends when creating a new student or updating an order — and they need to return more than just a body: the correct HTTP status code, and sometimes custom headers. @RequestBody and ResponseEntity are the two tools that make this possible.

What You Will Learn
  • How @RequestBody converts incoming JSON into a Java object.
  • How Spring Boot's built-in Jackson library performs that conversion.
  • How ResponseEntity lets you control status code, headers, and body together.
  • How to combine @RequestBody and ResponseEntity in one endpoint.

@RequestBody

@RequestBody tells Spring to take the raw body of an incoming HTTP request — typically JSON — and convert it into a Java object, binding it to the annotated method parameter. Start with a simple model class.

public class Student {
private Long id;
private String name;
private String email;
// getters and setters
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
}
@RestController
@RequestMapping("/api/students")
public class StudentController {
@PostMapping
public String createStudent(@RequestBody Student student) {
return "Created student: " + student.getName() + " (" + student.getEmail() + ")";
}
}
Example Request

Click Run to see what this code prints.

How Spring Boot Deserializes JSON

Spring Boot's web starter includes the Jackson library by default, which handles the conversion between JSON text and Java objects automatically. Jackson matches JSON keys to your class's fields using standard getter/setter naming conventions, so as long as your model class exposes public getters and setters (or is a record), you rarely need to write any conversion code yourself. This same Jackson mapper also handles serializing your Java objects back into JSON for the response, which is why returning a plain object or list from a controller method just works.

ResponseEntity

When a controller method returns a plain object or String, Spring Boot always responds with HTTP 200 OK. That is fine for reads, but a POST that creates a resource should return 201 Created, and a failed lookup should return 404 Not Found. ResponseEntity<T> wraps your response body together with an explicit status code, and optionally custom headers, giving you full control.

@GetMapping("/{id}")
public ResponseEntity<Student> getStudent(@PathVariable Long id) {
Student student = findStudentById(id);
if (student == null) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok(student);
}
Example Requests

Click Run to see what this code prints.

Combining Both

@RequestBody and ResponseEntity are used together constantly: read the incoming JSON as a Java object, do something with it, then return a ResponseEntity with the exact status code the situation calls for.

@PostMapping
public ResponseEntity<Student> createStudent(@RequestBody Student student) {
student.setId(generateNextId());
saveStudent(student);
return ResponseEntity.status(HttpStatus.CREATED).body(student);
}
Example Request

Click Run to see what this code prints.

Common Mistakes

Avoid These Mistakes
  • Forgetting the Content-Type: application/json header when sending a request body — without it, Spring cannot tell Jackson how to parse the payload.
  • Returning a plain object from every endpoint, which always sends 200 OK even when the operation created a resource or found nothing.
  • Not adding a no-argument constructor to a model class, which breaks Jackson's default deserialization in some configurations.
  • Calling ResponseEntity.ok(null) instead of ResponseEntity.notFound().build() when a resource isn't found, which sends a misleading 200 with an empty body.

Best Practices

  • Return ResponseEntity from any endpoint where the status code matters — creates, updates, deletes, and lookups that might not find anything.
  • Use 201 Created for successful POST requests, ideally with a Location header pointing to the new resource.
  • Use 404 Not Found rather than 200 with a null or empty body when a lookup fails.
  • Keep request/response model classes simple and dedicated to the API shape, separate from your database entity classes once your app grows.

Frequently Asked Questions

No. spring-boot-starter-web already pulls in Jackson, so JSON serialization and deserialization work out of the box with no extra configuration.

By default, Jackson ignores unknown JSON properties silently. This behavior can be changed with @JsonIgnoreProperties or global configuration if you want stricter validation.

Yes. ResponseEntity.noContent().build() returns 204 No Content, and ResponseEntity.notFound().build() returns 404 with no body — both common for DELETE and failed-lookup responses.

No. For simple GET endpoints that always succeed and always return 200, returning the object directly is perfectly fine. ResponseEntity is most valuable when the status code needs to vary.

Key Takeaways

  • @RequestBody deserializes an incoming JSON payload into a Java object using Jackson.
  • ResponseEntity<T> lets you control the exact status code, headers, and body of a response.
  • 201 Created for successful creates and 404 Not Found for missing resources are common ResponseEntity patterns.
  • @RequestBody and ResponseEntity are typically used together in create, update, and lookup endpoints.

Summary

You can now accept structured JSON input and return precisely the status code your API contract requires. In the next lesson, you'll put both together into a complete CRUD controller for a single resource, backed by an in-memory list.

Next Lesson →

Building a REST API (CRUD)