5

I have an Spring MVC application which has @Controller s and @RestController s. I was thinking that: When I have some Exception at my @Controller, It gonna be handled by my @ControllerAdvice and when I have some Exception at my @RestController, It gonna be handled by my @RestControllerAdvice... But now I think It's not how things should work, because my @ControllerAdvice are catching everything, even any exception that is thrown by @RestController...I do not know if this should happen. Here my code:

 @ControllerAdvice
 public class ExceptionHandlerController {

 private final String DEFAULT_ERROR_VIEW = "error/default";

  @ExceptionHandler(Exception.class)
  public ModelAndView defaultErrorHandler(HttpServletRequest req, Exception e) 
  {   
      ModelAndView mav = new ModelAndView();
      mav.addObject("exception", e);
      mav.addObject("danger", e.getMessage());
      mav.addObject("url", req.getRequestURL());
      mav.setViewName(DEFAULT_ERROR_VIEW);
      return mav;
  }
}


@RestControllerAdvice
public class ExceptionHandlerRestController {

  @ExceptionHandler(Exception.class)
  public ResponseEntity<String> defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {
      return new ResponseEntity<>(" test "+e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);        
  }    
}
Houssam Badri
  • 2,441
  • 3
  • 29
  • 60
Andre
  • 652
  • 2
  • 7
  • 23

2 Answers2

10

Yeah @RestControllerAdvice doesn't work that way. It's just a @ControllerAdvice with @ResponseBody automatically assumed. See @RestControllerAdvice vs @ControllerAdvice.

If you wanted one @ControllerAdvice to work with one controller and one to work with the other then if you put your controllers in separate packages you should be able to do this by doing:

@ControllerAdvice("my.controller1.package")

However, the whole point of @ControllerAdvice is to share common functionality of your separate @Controllers between each other so if you want them to do separate things you might be better off just putting the methods inside the @Controllers themselves.

Plog
  • 9,164
  • 5
  • 41
  • 66
  • Thanks, So if I put my Controllers and RestControllers at some separeted packages I will be able to do something like that? @ControllerAdvice("com.controller") and @RestControllerAdvice("com.controller.rest"), so Exceptions at controller will be andled by ControllerAdvice and Exceptions at controller.rest will be andled by RestControllerAdvice? – Andre Aug 11 '17 at 10:07
  • ControllerAdvice still handle everything... Maybe more specific package, I will try now... – Andre Aug 11 '17 at 10:10
  • 1
    Yeah now works.... I have changed packages to @RestControllerAdvice("com.rest.controller") instead of @RestControllerAdvice("com.controller.rest") and now works. – Andre Aug 11 '17 at 10:15
  • Good Im glad I could help! :) – Plog Aug 11 '17 at 10:16
0

If you want @RestControllerAdvice to handle only exceptions thrown from @RestController, then you can qualify it with the annotations attribute:

@RestControllerAdvice(annotations = RestController.class)

You may need @Order tag if you happen to have several other @ControllerAdvice.

Kenston Choi
  • 2,862
  • 1
  • 27
  • 37