Spring’s RequestBody and ResponseBody Annotations

1. Introduction

In this quick tutorial, we provide a concise overview of the Spring @RequestBody and @ResponseBody annotations.

2. @RequestBody

Simply put, the @RequestBody annotation maps the HttpRequest body to a transfer or domain object, enabling automatic deserialization of the inbound HttpRequest body onto a Java object.

First, let’s have a look at a Spring controller method:

@PostMapping("/request")
public ResponseEntity postController(
  @RequestBody LoginForm loginForm) {
 
    exampleService.fakeAuthenticate(loginForm);
    return ResponseEntity.ok(HttpStatus.OK);
}

Spring automatically deserializes the JSON into a Java type, assuming an appropriate one is specified.

By default, the type we annotate with the @RequestBody annotation must correspond to the JSON sent from our client-side controller:

public class LoginForm {
    private String username;
    private String password;
    // ...
}

Here, the object we use to represent the HttpRequest body maps to our LoginForm object.

Let’s test this using CURL:

curl -i \
-H "Accept: application/json" \
-H "Content-Type:application/json" \
-X POST --data 
  '{"username": "johnny", "password": "password"}' "https://localhost:8080/.../request"

This is all we need for a Spring REST API and an Angular client using the @RequestBody annotation.

3. @ResponseBody

The @ResponseBody annotation tells a controller that the object returned is automatically serialized into JSON and passed back into the HttpResponse object.

Suppose we have a custom Response object:

public class ResponseTransfer {
    private String text; 
    
    // standard getters/setters
}

Next, the associated controller can be implemented:

@Controller
@RequestMapping("/post")
public class ExamplePostController {

    @Autowired
    ExampleService exampleService;

    @PostMapping("/response")
    @ResponseBody
    public ResponseTransfer postResponseController(
      @RequestBody LoginForm loginForm) {
        return new ResponseTransfer("Thanks For Posting!!!");
     }
}

In the developer console of our browser or using a tool like Postman, we can see the following response:

{"text":"Thanks For Posting!!!"}

Remember, we don’t need to annotate the @RestController-annotated controllers with the @ResponseBody annotation since Spring does it by default.

3.1. Setting the Content Type

When we use the @ResponseBody annotation, we’re still able to explicitly set the content type that our method returns.

For that, we can use the @RequestMapping‘s produces attribute. Note that annotations like @PostMapping@GetMapping, etc. define aliases for that parameter.

Let’s now add a new endpoint that sends a JSON response:

@PostMapping(value = "/content", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ResponseTransfer postResponseJsonContent(
  @RequestBody LoginForm loginForm) {
    return new ResponseTransfer("JSON Content!");
}

In the example, we used the MediaType.APPLICATION_JSON_VALUE constant. Alternatively, we can use application/json directly.

Next, let’s implement a new method, mapped to the same /content path, but returning XML content instead:

@PostMapping(value = "/content", produces = MediaType.APPLICATION_XML_VALUE)
@ResponseBody
public ResponseTransfer postResponseXmlContent(
  @RequestBody LoginForm loginForm) {
    return new ResponseTransfer("XML Content!");
}

Now, depending on the value of an Accept parameter sent in the request’s header, we’ll get different responses.

Let’s see this in action:

curl -i \ 
-H "Accept: application/json" \ 
-H "Content-Type:application/json" \ 
-X POST --data 
  '{"username": "johnny", "password": "password"}' "https://localhost:8080/.../content"

The CURL command returns a JSON response:

HTTP/1.1 200
Content-Type: application/json
Transfer-Encoding: chunked
Date: Thu, 20 Feb 2020 19:43:06 GMT

{"text":"JSON Content!"}

Now, let’s change the Accept parameter:

curl -i \
-H "Accept: application/xml" \
-H "Content-Type:application/json" \
-X POST --data
  '{"username": "johnny", "password": "password"}' "https://localhost:8080/.../content"

As anticipated, we get an XML content this time:

HTTP/1.1 200
Content-Type: application/xml
Transfer-Encoding: chunked
Date: Thu, 20 Feb 2020 19:43:19 GMT

<ResponseTransfer><text>XML Content!</text></ResponseTransfer>

4. Conclusion

We’ve built a simple Angular client for the Spring app that demonstrates how to use the @RequestBody and @ResponseBody annotations.

Additionally, we showed how to set a content type when using @ResponseBody.

As always, code samples are available over on GitHub.

Related posts:

Java Program to Find Transpose of a Graph Matrix
Jackson – Unmarshall to Collection/Array
OAuth2 for a Spring REST API – Handle the Refresh Token in AngularJS
Weak References in Java
Converting a Stack Trace to a String in Java
Java Program to Implement Max-Flow Min-Cut Theorem
Using Optional with Jackson
Java Program to Describe the Representation of Graph using Incidence List
HttpClient Timeout
Java Program to Implement AA Tree
Tạo chương trình Java đầu tiên sử dụng Eclipse
Hướng dẫn Java Design Pattern – Object Pool
Giới thiệu Swagger – Công cụ document cho RESTfull APIs
@Before vs @BeforeClass vs @BeforeEach vs @BeforeAll
Deque và ArrayDeque trong Java
Java Program to Perform Insertion in a BST
Java Program to Implement SynchronosQueue API
Using a Custom Spring MVC’s Handler Interceptor to Manage Sessions
Quick Guide to Spring MVC with Velocity
Java Program to Implement Queue using Linked List
Spring Boot - File Handling
Java Program to Implement ConcurrentSkipListMap API
Guide to DelayQueue
Java Program to Find Whether a Path Exists Between 2 Given Nodes
Java Program to Find the Nearest Neighbor Using K-D Tree Search
Java Program to Compare Binary and Sequential Search
Làm thế nào tạo instance của một class mà không gọi từ khóa new?
Java Program to Find the Peak Element of an Array O(n) time (Naive Method)
A Guide to Java 9 Modularity
Java Program to Implement K Way Merge Algorithm
Java Program to Implement Slicker Algorithm that avoids Triangulation to Find Area of a Polygon
Filtering a Stream of Optionals in Java