Spring Boot:无法捕获@ControllerAdvice中的异常

问题描述 投票:0回答:1

我有 2 个异常处理程序类,用

@RestControllerAdvice
和:

注释

我使用第一个作为全局异常处理程序来捕获异常:

@RestControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {

    @Override
    @ResponseStatus(HttpStatus.UNPROCESSABLE_ENTITY)
    protected ResponseEntity<Object> handleMethodArgumentNotValid(...) {
      // ...
    }

    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ResponseEntity<Object> handleAllUncaughtException(Exception ex, WebRequest request) {
        // ...
    }

    // code omitted for clarity
}

第二个用于验证异常(我创建自定义验证):

@RestControllerAdvice
public class ValidationExceptionHandler { // did not extend from extends ResponseEntityExceptionHandler

    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseStatus(HttpStatus.UNPROCESSABLE_ENTITY)
    protected ValidationErrorResponse onConstraintValidationException(ConstraintViolationException e) {
        // ...
    }
}

当我将

onConstraintValidationException
移动到
GlobalExceptionHandler
类时,我捕获验证异常并显示相应的消息。但是当它在第二个 ControllerAdvice 类 (
ValidationExceptionHandler
) 中时,如上所示,代码不会命中
onConstraintValidationException
方法。

我也尝试过从

ResponseEntityExceptionHandler
延长第二堂课,但没有任何意义。

那么,问题是什么以及如何解决它?

java spring spring-boot validation exception
1个回答
1
投票

在你的情况下,这可能是优先级问题......第一个异常处理程序具有最高优先级,并且可能handleAllUncaughtException将捕获所有异常。

要在第二个处理程序 (ValidationExceptionHandler) 中捕获 ConstraintViolationException,您应该给予它最高优先级,如下所示:

@RestControllerAdvice
@Order(Ordered.HIGHEST_PRECEDENCE)
public class ValidationExceptionHandler { 

以及第一个最低的:

@RestControllerAdvice
@Order(Ordered.LOWEST_PRECEDENCE)
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {

可以看看这个讨论,了解更多关于它是如何工作的并有一些替代解决方案可能会很有趣: 设置多个@ControllerAdvice @ExceptionHandlers的优先级

编辑:如果您需要更灵活的东西或创建更复杂的处理程序层次结构,您可以在 Order 注释中使用简单的整数。 最低值,最高优先级。 所以像这样的东西也可以工作:

@RestControllerAdvice
@Order(-1)
public class ValidationExceptionHandler { 
//...

@RestControllerAdvice
@Order(0)
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
//...

在订购的源代码中,您有:

public interface Ordered {

/**
 * Useful constant for the highest precedence value.
 * @see java.lang.Integer#MIN_VALUE
 */
int HIGHEST_PRECEDENCE = Integer.MIN_VALUE;

/**
 * Useful constant for the lowest precedence value.
 * @see java.lang.Integer#MAX_VALUE
 */
int LOWEST_PRECEDENCE = Integer.MAX_VALUE;

在 Order 注释中,您可以看到默认值是 LOWEST_PRECEDENCE (Integer.MAX_VALUE):

public @interface Order {

/**
 * The order value.
 * <p>Default is {@link Ordered#LOWEST_PRECEDENCE}.
 * @see Ordered#getOrder()
 */
    int value() default Ordered.LOWEST_PRECEDENCE;

}
© www.soinside.com 2019 - 2024. All rights reserved.