68
  • What are the major difference between @RestControllerAdvice and @ControllerAdvice ??
  • Is it we should always use @RestControllerAdvice for rest services and @ControllerAdvice MVC ?
Om.
  • 2,532
  • 4
  • 22
  • 22

5 Answers5

79

@RestControllerAdvice is just a syntactic sugar for @ControllerAdvice + @ResponseBody, you can look here.

Is it we should always use @RestControllerAdvice for rest services and @ControllerAdvice MVC?

Again, as mentioned above, @ControllerAdvice can be used even for REST web services as well, but you need to additionally use @ResponseBody.

André Gasser
  • 1,065
  • 2
  • 14
  • 34
Vasu
  • 21,832
  • 11
  • 51
  • 67
24

In addition, we can just understand it as:

@RestControler = @Controller + @ResponseBody

@RestControllerAdvice = @ControllerAdvice + @ResponseBody.

Keeping in mind that @RestControllerAdvice is more convenient annotation for handling Exception with RestfulApi.

Example os usage:

@RestControllerAdvice
public class WebRestControllerAdvice {
  
  @ExceptionHandler(CustomNotFoundException.class)
  public ResponseMsg handleNotFoundException(CustomNotFoundException ex) {
    return new ResponseMsg(ex.getMessage());
  }
}

In that case any exception instanceOf CustomNotFoundException will be thrown in body of response.

Example extracted here: https://grokonez.com/spring-framework/spring-mvc/use-restcontrolleradvice-new-features-spring-framework-4-3

Abdullah Khan
  • 12,010
  • 6
  • 65
  • 78
Eddy Bayonne
  • 2,448
  • 1
  • 17
  • 23
  • 1
    Did you mean "@RestControllerAdvice" in this statement: "Keeping in mind that @ControllerAdvice is more convenient annotation for handling Exception with RestfulApi." – huypham99 Mar 20 '21 at 04:00
  • The link is broken. – Honza Zidek Jan 30 '22 at 23:30
  • If you want to modify the status, or add headers in the wrapping ResponseEntity, how would you do that with `@RestControllerAdvice`? – laegirl May 31 '23 at 08:29
5

Exception: A good REST API should handle the exception properly and send the proper response to the user. The user should not be rendered with any unhandled exception. A REST API developer will have two requirements related to error handling.

  1. Common place for Error handling
  2. Similar Error Response body with a proper HTTP status code across APIs

@RestControllerAdvice is the combination of both @ControllerAdvice and @ResponseBody

The @ControllerAdvice annotation was first introduced in Spring 3.2.

We can use the @ControllerAdvice annotation for handling exceptions in the RESTful Services but we need to add @ResponseBody separately.

Note:
GlobalExceptionHandler was annotated with @ControllerAdvice, thus it is going to intercept exceptions from controllers accross the application.

Prasenjit Mahato
  • 1,174
  • 15
  • 10
4

The differences between @RestControllerAdvice and @ControllerAdvice is :

@RestControllerAdvice = @ControllerAdvice + @ResponseBody. - we can use in REST web services.

@ControllerAdvice - We can use in both MVC and Rest web services, need to provide the ResponseBody if we use this in Rest web services.

For Example :

Exception Class:

@ResponseStatus(value = HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends Exception{

    private static final long serialVersionUID = 1L;
    public ResourceNotFoundException(String message){
        super(message);
    }
}

usage of the above exception in Rest Web Service.

 @RestControllerAdvice
 public class MyRestControllerAdviceHandler {
     
 @ExceptionHandler(ResourceNotFoundException.class)
      public ResponseMsg resourceNotFoundException(ResourceNotFoundException ex) {
        ResponseMsg resMsg = new ResponseMsg(ex.getMessage());
        return resMsg;
      }
    
}

usage of the above exception in MVC.

@ControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity<?> resourceNotFoundException(ResourceNotFoundException ex) {
        return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND);
    }
}
Lova Chittumuri
  • 2,994
  • 1
  • 30
  • 33
2

If you use @ControllerAdvice and return your error object from a method then it will look for a view with the name of your error object so instead of returning the expected response it will return 404 for not founding a view page with that name

@ControllerAdvice
public class CustomizedExceptionHandler {
@ExceptionHandler({ UserNotFoundException.class })
@ResponseStatus(code = HttpStatus.BAD_REQUEST)
public ExceptionResponce handleUserNotException(Exception ex, WebRequest request) throws Exception {
    ExceptionResponce exceptionResponce = new ExceptionResponce(new Date(), ex.getMessage(),
            request.getDescription(false));
    return exceptionResponce;


}

}

As in the above code, I want to return 400 (BAD_REQUEST) but instead of 400, it is returning 404(NOT_FOUND)

enter image description here

You can solve this issue by using any of the below ways

  1. add @ResponseBody to your method or class.
  2. Use @RestControllerAdvice.
  3. Or you can wrap your error object in ResponseEntity.

After using either of the above ways it returns the correct response enter image description here

Chaman Jain
  • 71
  • 1
  • 2