java - Spring:RestController 和 Controller 的不同异常处理程序

标签 java spring rest spring-mvc exception-handling

在 Spring 中,您可以通过 @ControllerAdvice 和 @ExceptionHandler 注释设置“全局”异常处理程序。我正在尝试利用这种机制来拥有两个全局异常处理程序:

  • RestControllerExceptionHandler - 对于使用 @RestController 注释的任何 Controller ,它应该以 json 形式返回错误响应
  • ControllerExceptionHandler - 应该为任何其他 Controller 将错误消息打印到屏幕(用 @Controller 注释)

问题是,当我声明这两个异常处理程序时,spring 总是使用 ControllerExceptionHandler 而从不使用 RestControllerExceptionHandler 来处理异常。

如何使这项工作? 顺便说一句:我尝试使用@Order 注释,但这似乎不起作用。

这是我的异常处理程序:

// should handle all exception for classes annotated with         
@ControllerAdvice(annotations = RestController.class)
public class RestControllerExceptionHandler {


  @ExceptionHandler(Exception.class)
  public ResponseEntity<ErrorResponse> handleUnexpectedException(Exception e) {

    // below object should be serialized to json
    ErrorResponse errorResponse = new ErrorResponse("asdasd"); 

    return new ResponseEntity<ErrorResponse>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR);
  }

// should handle exceptions for all the other controllers
@ControllerAdvice(annotations = Controller.class)
public class ControllerExceptionHandler {


  @ExceptionHandler(Exception.class)
  public ResponseEntity<String> handleUnexpectedException(Exception e) {
    return new ResponseEntity<String>("Unexpected exception, HttpStatus.INTERNAL_SERVER_ERROR);
  }


}
}

当我删除 ControllerExceptionHandlerRestControllerExceptionHandler 被 spring 正确调用(仅适用于用 @RestController 注释的类)......但是当我添加了 ControllerExceptionHandler,然后所有内容都通过 ControllerExceptionHandler。为什么?

最佳答案

经过更深入的调查,字母顺序似乎很重要:/。

当我将 RestControllerExceptionHandler 重命名为 ARestControllerExceptionHandler(按字母顺序排列在 ControllerExceptionHandler 之前)时,一切都按预期工作! ARestControllerExceptionHandler 正确处理来自 RestControllers 的异常,ControllerExceptionHandler 处理来自其他 Controller 的异常。

我为此在 Spring 创建了一个错误:https://jira.spring.io/browse/SPR-15432

--- 编辑:

我收到了 SPR-15432 的答案,其中建议可以使用 @Order (org.springframework.core.annotation.Order) 注释来解决这种情况或者通过实现 Ordered 接口(interface)。

这以前对我不起作用,但似乎我导入了错误的 @Order 注释。(来自 log4j2 而不是 spring)。解决这个问题后它就可以工作了。固定版本如下:

// should handle all exception for classes annotated with         
@ControllerAdvice(annotations = RestController.class)
@Order(1) // NOTE: order 1 here
public class RestControllerExceptionHandler {


  @ExceptionHandler(Exception.class)
  public ResponseEntity<ErrorResponse> handleUnexpectedException(Exception e) {

    // below object should be serialized to json
    ErrorResponse errorResponse = new ErrorResponse("asdasd"); 

    return new ResponseEntity<ErrorResponse>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR);
  }
}
// should handle exceptions for all the other controllers
@ControllerAdvice(annotations = Controller.class)
@Order(2)  // NOTE: order 2 here
public class ControllerExceptionHandler {


  @ExceptionHandler(Exception.class)
  public ResponseEntity<String> handleUnexpectedException(Exception e) {
    return new ResponseEntity<String>("Unexpected exception, HttpStatus.INTERNAL_SERVER_ERROR);
  }
}

关于java - Spring:RestController 和 Controller 的不同异常处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43325685/

相关文章:

rest - 无法使用 REST API 从 Bamboo 检索结果

java - 如果 HTML 代码没有更改,如何检查图像是否已更改?

java - DefaultTableModel 正在保存到文件,但如何加载该文件以再次使用它?

rest - Neo4j 服务器与嵌入式

java - 授权不起作用(Spring Security)

java - 我们可以使用 Spring Boot 对 Nodejs 应用程序进行身份验证吗?

rest - 如何使用 Azure DevOps REST API 创建新的构建管道?

java - 为什么 headless (headless) NetLogo 模拟在高端计算机集群上的运行速度比在台式机上慢?

java - 文件IO和异常处理错误

spring - Autowiring 不适用于 servlet