You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot 2.7.5升级后javax.validation.ValidationException失效问题

解决Spring Boot 2.7.5中javax.validation.ValidationException异常抛出异常的问题

问题分析

Spring Boot 2.7.x 对Spring Security和校验模块的默认配置做了调整,尤其是集成Spring Security的场景下,自定义的javax.validation.ValidationException可能会被Security的异常处理器优先捕获,导致你的全局异常处理器无法拦截到目标异常,转而返回401 Unauthorized错误,而不是你预期的自定义提示。

解决方案

1. 调整Spring Security异常处理逻辑

如果项目用了Spring Security,需要在Security配置里让自定义的ValidationException绕过默认的401处理,交给全局异常处理器:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            // 其他原有配置...
            .exceptionHandling()
                .authenticationEntryPoint((request, response, authException) -> {
                    // 判断异常根源是否是自定义的ValidationException
                    if (authException.getCause() instanceof ValidationException) {
                        throw (ValidationException) authException.getCause();
                    }
                    // 其他情况走默认401响应
                    response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage());
                });
    }
}

2. 确保全局异常处理器配置正确

检查全局异常处理器的注解和异常捕获方法是否正确:

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(ValidationException.class)
    public ResponseEntity<Map<String, Object>> handleValidationException(ValidationException ex) {
        Map<String, Object> errorResponse = new HashMap<>();
        errorResponse.put("code", HttpStatus.BAD_REQUEST.value());
        errorResponse.put("message", ex.getMessage());
        return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST);
    }

    // 其他异常处理方法...
}

如果你的异常是ValidationException的子类,需要在@ExceptionHandler里指定子类类型,或者确保父类类型能覆盖到。

3. 清理依赖冲突

Spring Boot 2.7.x的spring-boot-starter-validation已经包含了校验API和hibernate-validator实现,检查pom.xml里是否有重复引入的javax.validation依赖,避免冲突:

<!-- 保留官方starter即可 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

<!-- 移除单独引入的validation-api依赖 -->
<!-- <dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
</dependency> -->

4. 检查业务代码的异常抛出逻辑

确保业务代码中是直接抛出ValidationException,没有被其他逻辑包装成Security相关异常:

@GetMapping("/users/{id}")
public User getUser(@PathVariable Long id) {
    return userRepository.findById(id)
        .orElseThrow(() -> new ValidationException("User not Found in the System"));
}

核心原因

Spring Boot 2.7.x升级了Spring Security版本,其中ExceptionTranslationFilter的异常处理逻辑有调整:当请求经过Security过滤器链时,若抛出的异常被判定为认证相关,会直接触发401响应,不会传递到全局异常处理器。通过上述配置可以让自定义的ValidationException绕过这个拦截,回到全局处理器处理。

内容的提问来源于stack exchange,提问作者Rose

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 14:02:24