@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ExceptionHandler(BusinessException.class) public String handleBusinessException(BusinessException ex) { log.error("[BUSINESSEXCEPTION - 来自 qn]", ex); return ex.getMessage(); * 数据库异常处理 * @param ex * @return @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ExceptionHandler(SQLException.class) public String handleSQLException(SQLException ex) { log.error("[SQLEXCEPTION - 来自 qn]", ex); return ErrorEnum.SQL_EXCEPTION.value(); * 全局异常捕捉处理 * @param ex * @return @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ExceptionHandler(value = Exception.class) public String globalExceptionHandle(Exception ex){ log.error("[EXCEPTION - 来自 qn]", ex); return ex.getMessage();

原想这,sqlExption放在Exception前面,所以应该会先执行。哈哈,其实不是。

在同一个自定义的ExceptionHandler类,定义多个异常处理器,他们的加载顺序如何决定?
结论:是由 ExceptionHandlerMethodResolver 通过递归查找调用链,内部自己判断决定的, 用户没办法直接干预 调用链越小,执行度越高

自定义异常处理类解决调用顺序问题

多个自定义的ExceptionHandler类的执行顺序就是被Spring加载到容器中Bean加载顺序。 用户可控

所以上面代码改造成两个类,并通过加@order来标识先后顺序( @Order 注解来指定实体Bean被加载到Spring容器的顺序,注解中的值越小越优先加载 ):

@Order(1)
@Slf4j
@RestControllerAdvice
public class SqlExceptionHandle {
     * 数据库异常处理
     * @param ex
     * @return
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(SQLException.class)
    public String handleSQLException(SQLException ex) {
        log.error("[SQLEXCEPTION - 来自 qn]", ex);
        return ErrorEnum.SQL_EXCEPTION.value();
@Order(100)
@RestControllerAdvice
@Slf4j
public class ExceptionHandle{
     * 业务异常处理
     * @param ex
     * @return
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(BusinessException.class)
    public String handleBusinessException(BusinessException ex) {
        log.error("[BUSINESSEXCEPTION - 来自 qn]", ex);
        return ex.getMessage();
     * 全局异常捕捉处理
     * @param ex
     * @return
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(value = Exception.class)
    public String globalExceptionHandle(Exception ex){
        log.error("[EXCEPTION - 来自 qn]", ex);
        return ex.getMessage();

这样,就可以实现sqlExceptionHandle先于ExceptionHandle生效的。

背景改造项目,自定义了多个异常,同时还要对数据库的sql异常做处理。如下:@RestControllerAdvice@Slf4jpublic class ExceptionHandle{ /** * 业务异常处理 * @param ex * @return */ @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ExceptionHandler(BusinessExcepti
在本系列文章的第一部分里,我们讨论了异常发生时,该返回给 REST API 调用者的异常表示(格式)的佳实践。   在本文(第二部分)中,我们将展示如何在使用 Spring MVC 编写的 REST API 中产生那些异常表述信息。   Spring 异常处理   Spring MVC 有两个主要方式来处理在调用 MVC 控制器(译注:Controller,下文统一为控制器)时抛出的异常:HandlerExceptionResolver 和 @ExceptionHandler 注解。   HandlerExceptionResolvers 对于用一种统一的方法来处理异常来说非常的理想,
@ExceptionHandler(value = BusinessException.class) @ResponseBody public ResultVO handlerSellerException(BusinessException e) { return ResultVOUtil.error(e.getException... 2个服务:A-common 和 BService,各自有异常处理器。 其中A中定义了通用的异常处理器,供所有服务直接调用。 但是B服务由于业务需求需要处理一些A中没有的异常,由于A中存在兜底逻辑:对Exception进行捕获,这个时候就要指定异常处理器的执行顺序Spring异常处理器是根据异常处理器被加载的顺序来顺序执行,比如:A->B->C ,如果B拦截并且处理了某个异常,就会直接抛出,C的异常处理器就执行不到了。 可以通过 @Order 注解来
第一种,直接在Controller层写@ExceptionHandler注解,对于指定异常,可以处理并返回一个视图或者body: @Controller public class HelloWorld { @RequestMapping("test") public String test(int flag) throws FileNotFoundException { if (1 == flag) { throw new FileNotFoundE
@ExceptionHandler() public String handleExeption2(Exception ex) { System.out.println("抛异常了:" + ex); ex.printStackTrace(); String resultStr = "异常:默认"; return resultStr; 当我们使用这 在springboot多模块中, common模块有全局异常处理, A模块引用了common模块, 且A模块中有自己的全局异常处理, 在有些服务中是A中的全局异常处理生效, 有些服务中是common模块中的全局异常处理生效. 非常疑惑, 了解后写下此篇. 先加载的@ControllerAdvice里如果存在@ExceptionHandler(xxException.class)是需要捕获的异常或其父,则将使用先加载的中的异常处理方式。如果没有,则看后面的@ControllerAd
要在 Spring Boot 中实现全局异常处理,你可以这样做: 1. 定义一个异常处理,并实现 Spring 的 `HandlerExceptionResolver` 接口或者使用 `@ControllerAdvice` 和 `@ExceptionHandler` 注解。 2. 在你的异常处理中,通过使用 `@ExceptionHandler` 注解来声明你要处理的异常型。 例如,假设你要处理所有型的异常,你可以这样写: ```java @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) public ResponseEntity<ErrorResponse> handleException(Exception ex) { // 处理异常并返回响应 ErrorResponse error = new ErrorResponse(); error.setMessage(ex.getMessage()); return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR); 在这个例子中,我们通过使用 `@ControllerAdvice` 注解声明了这个是一个全局异常处理,并使用 `@ExceptionHandler` 注解声明了要处理的异常型是 `Exception`。你也可以声明多个 `@ExceptionHandler` 注解来处理不同型的异常。 然后,你可以在你的应用程序中抛出异常,Spring 会自动调用你定义的异常处理方法来处理异常。 注意:如果你使用的是 Spring Boot 2.x 版本,你可以通过实现 `ErrorController` 接口来实现全局异常处理