【问题标题】:How to have two ControllerAdvice in the same SpringMvc application如何在同一个 SpringMvc 应用程序中有两个 ControllerAdvice
【发布时间】:2016-04-25 00:56:48
【问题描述】:

我想通过两种方式管理简单控制器或 RestController 抛出的异常: 1)html重定向 2) json错误

我测试了下面的代码:

@ControllerAdvice(annotations = Controller.class)
public class ExceptionHandlerController
{
    @ExceptionHandler(Exception.class)
    public ModelAndView handleException(HttpServletRequest _req, Exception _ex)
    {
        K_LOGGER.info("test");
        return new ModelAndView();
    }
}

@ControllerAdvice(annotations = RestController.class)
public class ExceptionHandlerRestController
{

    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleException(HttpServletRequest _req, Exception _ex)
    {
        return new ResponseEntity<>("test", HttpStatus.INTERNAL_SERVER_ERROR);
    }

}

@RestController
public class GreetingController
{
    @RequestMapping("/greetingexception")
    public Greeting greetingException(@RequestParam(value = "name", defaultValue = "World") String name)
        throws Exception
    {
        throw new Exception();
    }
}

它不能正常工作,我总是通过ExceptionHandlerController而不是ExceptionHandlerRestController。

我认为这是因为@RestController 继承了@Controller。

您还有其他解决方案吗?

【问题讨论】:

    标签: java ajax spring-mvc spring-boot


    【解决方案1】:

    eg04lt3r 答案是正确的,尽管更多细节可能对某人有用。

    如果您有全局 @ControllerAdvice 并希望在您的一个控制器中以不同的方式处理某些异常,您需要在 @ControllerAdvice 上设置 @Order(Ordered.HIGHEST_PRECEDENCE),它应该具有更高的优先级。

    例如:

    @ControllerAdvice
    public class GeneralExceptionHandler {
    
        @ExceptionHandler(Exception.class)
        protected ResponseEntity<Error> handleException(Exception ex) {
            ...
        }
    }
    
    @ControllerAdvice(assignableTypes = MyController.class)
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public class MyExceptionHandler {
    
        @ExceptionHandler(Exception.class)
        protected ResponseEntity<Error> handleException(Exception ex) {
            ...
        }
    }
    

    @Order 是必需的,因为在启动时,其中一个处理程序将自动以更高的顺序注册,无论如何,您的异常处理将变得不可预测。例如,我最近看到一个案例,如果您使用 bootRun gradle task MyExceptionHandler 启动应用程序是主要的,但是当以 jar 启动时 GeneralExceptionHandler 是主要的。

    【讨论】:

      【解决方案2】:

      尝试将@Order(Ordered.HIGHEST_PRECEDENCE) 注释添加到其余异常处理程序。它可能对你有帮助。

      【讨论】:

      • 谢谢很多,它有效。为什么优先级很重要? Spring根据加载顺序应用ControllerAdvices?
      • 在这种情况下他先定义了,因为它们处理相同的异常。当解析器尝试查找异常处理程序时,如果您没有提供订单,他首先定义。
      猜你喜欢
      • 1970-01-01
      • 2012-02-22
      • 1970-01-01
      • 2010-12-21
      • 2017-01-22
      • 2017-06-12
      • 2010-11-13
      • 2018-04-23
      • 1970-01-01
      相关资源
      最近更新 更多