Spring RequestBody and ResponseBody Explained

RequestBody and ResponseBody

Spring RequestBody and ResponseBody annotations are used in Spring controllers, where we want to bind web requests to method parameters (RequestBody) or method return value (ResponseBody) to Web response. In this article, we will cover some quick examples of using both these annotations. Although Spring supports different styles of writing controller and accessing request, response object, using RequestBody and ResponseBody helps writing code quickly as all the parameters are already available in the controller, and Spring takes care of serialization and deserialization. Although using ResponseBody is not required if we use @RestController annotation. More about @Restcontroller can be found here @RestController

Serialization

Data sent over HTTP to server resources (Like a REST Controller) needs to be converted from serialized version to Objects. We can have different types of REST controllers based on the payload they support. For instance, we can design the REST controller to accept/send XML, JSON, TEXT, or HTML payloads/response. The Controller then should be able to read those data acts on it and return the response. Spring uses HTTP Message converters to convert the HTTP request body into domain object [deserialize request body to domain object], and to convert Domain object back to HTTP response body while returning the response. Spring provides a number of MessageConvertes like bellow, StringHttpMessageConverter: Read Write String
FormHttpMessageConverter: Read Write HTTP Form Data
MappingJackson2HttpMessageConverter: Read Write JSON
MappingJackson2XmlHttpMessageConverter: Read Write XML etc.
@RequestBody and @ResponseBody body annotation behind the scene uses these Message converter to serialize or deserialize the data. Following section, we will see each example of these two annotations.

@RequestBody annotations

Typically in each controller, we can have multiple methods. Each method is tied to a specific HTTP request path via @RequestMapping. That's how Spring knows for an incoming request which method needs to be invoked. If a method parameter is annotated with @RequestBody, Spring will bind the incoming HTTP request body (payload) to the parameter of the respective method tied to the request path. While doing that, Spring will [behind the scenes] use HTTP Message converters to convert the HTTP request body into domain object [deserialize request body to domain object], based on Accept header present in the request.

@ResponseBody Annotation

Similar to the @RequestBody annotation the @ResponseBody annotation is used to convert the return type of the method to the HTTP response. Here also Spring will use Message Converter to convert the return type of the method to the HTTP response body, set the HTTP headers, and HTTP status.
Let's see an example, where we bind a JSON payload to a @RequestBody method parameter. Following the example, we will create a REST endpoint that can take a JSON payload to create a blog category object and then return the response back to the client.
Our BlogCategory Model
The model object representing a blog category.
public class BlogCategory {
  private String id;
  private String name;
  //Getters and Setters removed for readability
}
Sample JSON Payload
This JSON payload can be used to populate the BlogCategory object.
{
    "id": "new_cat",
    "name": "new cat neme"
}
A controller method to add a new category.
In the following example, we mark the method parameters "input" with @RequestBody. We also mark the return type of the method ResponseEntity with @ResponseBody.
@RequestMapping(value = {"/categories"}, method = RequestMethod.POST,
      produces = MediaType.APPLICATION_JSON_VALUE)
  public @ResponseBody ResponseEntity addCats(@RequestBody BlogCategory input) {
    try {
      log.info("payload: " + input);
      blogService.addBlogCategories(input);
      return ResponseEntity.ok().body(input);
    } catch (Exception e) {
      log.info(e.getMessage());
      return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
    }
  }
As a result, when the controller receives a request, the payload will be parsed and used to populate an instance of the BlogCategory object. Similarly when returning Web response back to client Spring will serialize the instance of and ResponseEntity to Web response.
Invoke API with Curl
We can invoke the API with payload by running the following curl command from a Terminal.
curl -X POST \
  http://localhost:8080/blogapi/categories \
  -H 'Content-Type: application/json' \
  -d '{
    "id": "new_cat",
    "name": "new cat neme"
}'
API Response
The API should return with the following JSON payload.
{
    "id": "new_cat",
    "name": "new cat neme"
}
Summary
  • @RequestBody annotation facilitates deserialize the payload to a domain object.
  • @ResponseBody annotation facilitates serialization of the domain object to the payload.
  • @ResponseBody annotation is not required if we use @RestController rather then @Controller to annotate our Controller class.
  • @RestController is recommended over using @ResponseBody.
  • Another option is to use ResponseEntity as a return type of the controller method.
Git Source code
  • git clone https://github.com/siddharthagit/spring-boot-references
  • cd spring-rest
  • mvn clean install
  • mvn spring-boot:run

    References

    No comments :

    Post a Comment

    Please leave your message queries or suggetions.