What is the best way to return different types of ResponseEntity in Spring MVC or Spring-Boot
I have written simple rest application using Spring MVC 4 (or Spring-Boot). Within the controller I have return ResponseEntity
. But in some cases I want to give success JSON and if there is validation error I want to give error JSON. Currently success and error responses are totally different, So I have created 2 classes for error and success. Within the controller I want to return ResponseEntity<Success>
, if the internal logic is okay. Otherwise I want to return ResponseEntity<Error>
. Is there any way to do it.
Success
and Error
are the 2 classes that i use to represent success and error response.
I recommend using Spring's @ControllerAdvice
to handle errors. Read this guide for a good introduction, starting at the section named "Spring Boot Error Handling". For an in-depth discussion, there's an article in the Spring.io blog that was updated on April, 2018.
A brief summary on how this works:
- Your controller method should only return
ResponseEntity<Success>
. It will not be responsible for returning error or exception responses. - You will implement a class that handles exceptions for all controllers. This class will be annotated with
@ControllerAdvice
- This controller advice class will contain methods annotated with
@ExceptionHandler
- Each exception handler method will be configured to handle one or more exception types. These methods are where you specify the response type for errors
- For your example, you would declare (in the controller advice class) an exception handler method for the validation error. The return type would be
ResponseEntity<Error>
With this approach, you only need to implement your controller exception handling in one place for all endpoints in your API. It also makes it easy for your API to have a uniform exception response structure across all endpoints. This simplifies exception handling for your clients.
You can return generic wildcard <?>
to return Success
and Error
on a same request mapping method
public ResponseEntity<?> method() {
boolean b = // some logic
if (b)
return new ResponseEntity<Success>(HttpStatus.OK);
else
return new ResponseEntity<Error>(HttpStatus.CONFLICT); //appropriate error code
}
@Mark Norman answer is the correct approach
i am not sure but, I think you can use @ResponseEntity
and @ResponseBody
and send 2 different one is Success and second is error message like :
@RequestMapping(value ="/book2", produces =MediaType.APPLICATION_JSON_VALUE )
@ResponseBody
Book bookInfo2() {
Book book = new Book();
book.setBookName("Ramcharitmanas");
book.setWriter("TulasiDas");
return book;
}
@RequestMapping(value ="/book3", produces =MediaType.APPLICATION_JSON_VALUE )
public ResponseEntity<Book> bookInfo3() {
Book book = new Book();
book.setBookName("Ramayan");
book.setWriter("Valmiki");
return ResponseEntity.accepted().body(book);
}
For more detail refer to this: http://www.concretepage.com/spring-4/spring-4-mvc-jsonp-example-with-rest-responsebody-responseentity
You can use a map with your object or string like bellow :
@RequestMapping(value = "/path",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ResponseEntity<Map<String,String>> getData(){
Map<String,String> response = new HashMap<String, String>();
boolean isValid = // some logic
if (isValid){
response.put("ok", "success saving data");
return ResponseEntity.accepted().body(response);
}
else{
response.put("error", "an error expected on processing file");
return ResponseEntity.badRequest().body(response);
}
}
Spring 2 introduced ResponseStatusException using this you can return String, different HTTP status code, DTO at the same time.
@PostMapping("/save")
public ResponseEntity<UserDto> saveUser(@RequestBody UserDto userDto) {
if(userDto.getId() != null) {
throw new ResponseStatusException(HttpStatus.NOT_ACCEPTABLE,"A new user cannot already have an ID");
}
return ResponseEntity.ok(userService.saveUser(userDto));
}