Spring Boot:@RestControllerAdvice无法捕获ConstraintViolationException问题
问题原因
你的两个@RestControllerAdvice类中,GlobalExceptionHandler包含了一个处理所有Exception的通用方法handleAllUncaughtException。虽然ValidationExceptionHandler中的方法针对更具体的ConstraintViolationException,但由于默认情况下Spring对多个@RestControllerAdvice类的优先级排序不明确,全局处理器的通用方法会被优先匹配,导致具体的校验异常处理器无法触发。
而当你把onConstraintValidationException移到GlobalExceptionHandler中时,Spring会在同一个类内部优先选择异常类型更具体的处理器方法,因此能正常触发。
解决方案
方案1:给校验异常处理器设置最高优先级
在ValidationExceptionHandler类上添加@Order(Ordered.HIGHEST_PRECEDENCE)注解,让Spring优先处理这个类中的异常处理器:
@RestControllerAdvice @Order(Ordered.HIGHEST_PRECEDENCE) public class ValidationExceptionHandler { @ExceptionHandler(ConstraintViolationException.class) @ResponseStatus(HttpStatus.UNPROCESSABLE_ENTITY) protected ValidationErrorResponse onConstraintValidationException(ConstraintViolationException e) { // 你的校验异常处理逻辑 } }
方案2:排除全局处理器对校验异常的处理(Spring 5.3+)
如果你的项目使用Spring 5.3及以上版本,可以在全局处理器的@ExceptionHandler注解中排除ConstraintViolationException,让具体处理器负责处理:
@ExceptionHandler(value = Exception.class, exclude = ConstraintViolationException.class) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) public ResponseEntity<Object> handleAllUncaughtException(Exception ex, WebRequest request) { // 原有全局异常处理逻辑 }
方案3:调整全局处理器的逻辑(不推荐)
在全局处理器的通用方法中,判断异常类型,若为ConstraintViolationException则重新抛出,交给校验异常处理器处理:
@ExceptionHandler(Exception.class) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) public ResponseEntity<Object> handleAllUncaughtException(Exception ex, WebRequest request) { if (ex instanceof ConstraintViolationException) { throw (ConstraintViolationException) ex; } // 原有全局异常处理逻辑 }
内容的提问来源于stack exchange,提问作者user19601508
相关产品推荐
相关产品推荐

