首页 > 解决方案 > 异常处理程序无法在 Spring Boot 应用程序上运行,从未调用过 @RestControllerAdvice,我使用的是低级客户端

问题描述

尝试设置一个全局自定义异常处理机制,该机制依赖于可以处理异常的 @RestControllerAdvice。

@RestControllerAdvice** 异常处理程序根本没有触发。在这里,我使用的是低级客户端。

我设置了以下控制器建议,以针对错误情况返回 API 合同:

我试图在下面添加

@ExceptionHandler(value = { ResponseException.class })
public ApiErrorResponse noHandlerFoundException(Exception ex) {
    LOG.error(ex.getCause().toString());
    int status = ((ResponseException) ex).getResponse().getStatusLine().getStatusCode();
    return new ApiErrorResponse(status, "<some message depending on status code>");
}

但看到相同的结果

pom.xml:

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
    </parent>

    <properties>
        <java.version>1.8</java.version>
    </properties>

全局控制器异常处理程序:

    @RestControllerAdvice
    public class GlobalControllerExceptionHandler extends ResponseEntityExceptionHandler{

        private static final Logger LOG = Logger.getLogger(GlobalControllerExceptionHandler.class);

        @ExceptionHandler(value = { ConstraintViolationException.class })
        @ResponseStatus(HttpStatus.BAD_REQUEST)
        public ApiErrorResponse constraintViolationException(ConstraintViolationException ex) {
            LOG.error(ex.getCause().toString());
            return new ApiErrorResponse(400, "Bad Request");
        }

        @ExceptionHandler(value = { NoHandlerFoundException.class })
        @ResponseStatus(HttpStatus.NOT_FOUND)
        public ApiErrorResponse noHandlerFoundException(Exception ex) {
            LOG.error(ex.getCause().toString());
            return new ApiErrorResponse(404, "Resource Not Found");
        }

        @ExceptionHandler(value = { Exception.class })
        @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
        public ApiErrorResponse unknownException(Exception ex) {
            LOG.error(ex.getCause().toString());
            return new ApiErrorResponse(500, "Internal Server Error");
        }
    }

ApiError 响应:

    public class ApiErrorResponse {

        private int status;
        private String message;

        public ApiErrorResponse(int status, String message) {
            this.status = status;
            this.message = message;
        }

        public int getStatus() {
            return status;
        }

        public String getMessage() {
            return message;
        }

        @Override
        public String toString() {
            return new ToStringBuilder(this).append(status)
                                            .append(message)
                                            .toString();
        }
    }

问题是当我使用 3rd 方库做某事时。

标签: spring-bootspring-mvcelasticsearchexception

解决方案


这是因为您尝试通过 javax.validation.ConstraintViolationException;ConstraintViolationException 处理嵌套异常是org.springframework.transaction.TransactionSystemException;

将处理程序更改为@ExceptionHandler(TransactionSystemException.class)

TransactionSystemException 不是一个理想的解决方案,但它确实有效。这个bug在最新版本的Spring Boot版本中得到修复:>= 2.4.0

在下面的链接中,您可以看到他们如何打开ConstraintViolationException

从 TransactionSystemException 解开 ConstraintViolationException

或者,您可以升级到:

// Gradle Config
plugins {
    id 'org.springframework.boot' version '2.4.0'
    id 'io.spring.dependency-management' version '1.0.10.RELEASE'
    id 'java'
}

从 Spring Boot 版本开始:>= 2.4.0,您现在可以处理嵌套异常。


推荐阅读