As part of the REST API with Spring series, in this post, we will get an overview of the Spring @RequestBody and @ResponseBody annotations.
Introduction
While working on the REST API, we may need to bind the HTTP request and response body with the domain object. Spring @RequestBody and @ResponseBody annotations used to bind these HTTP request/response. Let’s have a closer look at these two Spring annotations.
1. Spring RequestBody Annotation
To put it in layman terms, the @RequestBody
annotation binds the HTTPRequest body to the domain object. Spring framework automatically de-serializes incoming HTTPRequest to the Java object using Http Message Converters .We pass the body of the request through a HttpMessageConverter
to resolve the method argument depending on the content type of the request.If above definitions seems complicated, the @RequestBody annotation allows us to retrieve the request’s body and automatically convert it to Java Object
To understand this, let’s take an example of the customer registration process.
- API need customer data for the registration.
- Customer full registration form, system will send customer data through HTTPRequest body.
Here is our registration data model.
package com.javadevjournal.restexample.data;
public class Registration {
private String firstName;
private String lastName;
private String email;
private int age;
private String password;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
Let’s create our REST control to accept this registration data.
@RestController
public class RegistrationController {
@Autowired
private CustomerService customerService;
@PostMapping("/registration")
public ResponseEntity < Customer > register(@RequestBody Registration registration) {
Customer customer = customerService.saveCustomer(mapCustomerData(registration));
return new ResponseEntity < Customer > (customer, HttpStatus.OK);
}
protected Customer mapCustomerData(Registration registration) {
Customer customer = new Customer(registration.getFirstName(), registration.getLastName(), registration.getEmail());
customer.setAge(registration.getAge());
return customer;
}
}
There are few important things in the above code.
- Spring framework will automatically deserialize the JSON into a Java type based on the
HTTPMessageConvertor
.
To test our application, use any REST Client (Postman etc.), send a POST request to the following URL http(s)://host: port/registration
with similar data.
{
"firstName":"first",
"lastName":"last",
"email":"[email protected]",
"age":"30"
}
We will get the following response from our REST Controller.
application/json;charset=UTF-8
transfer-encoding:chunked
date:Tue, 07 Aug 2018 02:49:39 GMT
{
"id": 5,
"firstName": "first",
"lastName": "last",
"email": "[email protected]",
"age": 30
}
As seen in this example, Spring automatically converting incoming JSON data in the HTTPRequestBody
to the Registration java object.
2. Spring ResponseBody Annotation
To put this in simple words, @ResponseBody
tell Spring framework to serialize a return object into JSON or XML and send this information back as part of the HTTPResponse.
With Spring 4.x, If we are using working on the REST API, we should not use @ResponseBody
on method level, but <@RestController
on a class level.@RestController
is a composed annotation that is itself a meta-annotated with @Controller
and @ResponseBody.
Let’s look at the previous example, our register method is returning Customer object and we like this to return as JSON in the HTTPResponse.Here is our Customer model.
public class Customer {
private Long id;
private String firstName;
private String lastName;
private String email;
private int age;
public Customer() {}
public Customer(String firstName, String lastName, String email) {
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
When we sent a POST request to our REST controller, we may get the following response from the controller
application/json;charset=UTF-8
transfer-encoding:chunked
date:Tue, 07 Aug 2018 02:49:39 GMT
{
"id": 5,
"firstName": "first",
"lastName": "last",
"email": "[email protected]",
"age": 30
}
With Spring 4.x, If you are using @RestController
, we don’t need to use the code>@ResponseBody annotation on the method level and the @RestController
annotation will add it automatically.Fore more details, please read.
In case we do not have the option to use @RestController
annotation, we need the following changes in our controller.
@Controller
public class RegController {
@Autowired
private CustomerService customerService;
@PostMapping("/new-registration")
public @ResponseBody Customer register(@RequestBody Registration registration) {
return customerService.saveCustomer(mapCustomerData(registration));
}
}
Summary
In this article, we covered Spring @RequestBody and @ResponseBody annotations. These annotations are important while building our REST API using Spring and Spring Boot. The code for this post is available on the GitHub.