Spring ResponseEntity Example

ResponseEntity

ResponseEntity class is used to represent HTTP response containing body, header and status. ResponseEntity class extends HttpEntity and used to encapsulate HTTP response. While writing the REST controller one of the common design questions is what should the controller method return? Also, we need to be cognizant about different REST endpoints and making sure all the responses maintain a standard pattern. All responses share common response building blocks like HTTP headers and HTTP Status. Using ResponseEntity is one of the options to write a REST controller, which helps in setting headers and status easily. ResponseEntity is not the only option we have while creating REST controllers. But It does provide some advantages In this short article, we will see the different ways of writing REST Controller and returning data from the controller.
How to handing serialize the data from the controller depends on the use case we are dealing with. But we should keep in mind about easy maintenance of code and maintaining request-response structure across different endpoints.
Using ResponseEntity is not only option to manipulate the response, but We can also return directly any Java object from the controller and let Spring do the serialization (Our Second example in this article).
For setting the HTTP status only we can use @ResponseStatus annotation.
For setting headers and status we can also javax.servlet.http.HttpServletResponse directly.

ResponseEntity Class

ResponseEntity Class is used to represent whole HTTP responses. It supports the
the message body,
headers,
status, etc.
Internally Response extends org.springframework.http.HttpEntity The advantage of using ResponseEntity is that it is easy to set headers status on this object directly which gets serialized as an HTTP response.
Let's see an example controller using ResponseEntity

Examples

Example 1: Controller with ResponseEntity
In this example, we are building a controller that returns a list of Tags as a response. Each tag is represented by a String object, so we are returning basically List
We are wrapping a list of tags received form service in ResponseEntity> object. We can then set the HTTP status on the ResponseEntity object. If everything looks good, we are setting the status "OK 200", else we are setting HTTP status " 500 Internal Server Error".
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.bootng.beans.AppException;

@RestController
@RequestMapping("/blogapi")
public class TagAPIController {

@RequestMapping(value = {"v1/tags"}, method = RequestMethod.GET,
      produces = MediaType.APPLICATION_JSON_VALUE)
  public ResponseEntity> getTagsV1() {
    try {
      List tags = blogService.getBlogTags();
      return ResponseEntity.ok().body(tags);
    } catch (AppException e) {
      log.error(e.getMessage());
      return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
    }
  }
}
Following is a controller that also does the same stuff as the above controller. That is the return list of Tags. But here we are not using ResponseEntity, rather we are sending the Object directly from the controller method
Let's see the example.
Example 2: Controller without ResponseEntity
Following controller which returns the list of Tags as a JSON response. Notice that the method returns List and not ResponseEntity.
package com.bootng;

import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.bootng.beans.AppException;


@RestController
@RequestMapping("/blogapi")
public class TagAPIController {

  private static final Logger log = LoggerFactory.getLogger(TagAPIController.class);

  @Autowired
  BlogService blogService;
  @RequestMapping(value = {"v3/tags"}, method = RequestMethod.GET,
      produces = MediaType.APPLICATION_JSON_VALUE)
  public List getTagsV3() {
    List tags = null;
    try {
      tags = blogService.getBlogTags();
    } catch (AppException e) {
      log.error(e.getMessage());
    }
    return tags;
  }
}
Response from both the above API / v3/tags and /v1/tags looks the same.
Example 3
In this example, we are writing the controller with HttpServletResponse as a parameter. This allows us to set the header and status directly on the object.
package com.bootng;
@RequestMapping(value = {"/welcome"}, method = RequestMethod.GET,
      produces = MediaType.APPLICATION_JSON_VALUE)
void welcome(HttpServletResponse response) throws IOException {
    response.setHeader("Custom-Header-Message-Type", "welcome_user");
response.setHeader("Custom-Header-Message-LANG", "en-us");
    response.setStatus(200);
    response.getWriter().println("Welcome");
}
Conclusions
  • We saw how to write a REST controller using ResponseEntity and without using ResponseEntity.
  • ResponseEntity makes it easy to set common HTTP Response elements like status code, headers, etc.
  • ResponseEntity is definitely useful but makes the overall controller method less readable the controller method return type is now ResponseEntity wrapped actual return type.

References

19 comments :

Please leave your message queries or suggetions.