在 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);
}
}
}
当我删除 ControllerExceptionHandler
时 RestControllerExceptionHandler
被 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/