SpringBoot 2.x下Jakarta Validation兼容问题解决方案咨询
解决方案
针对你遇到的SpringBoot 2.2下javax与jakarta校验冲突问题,最有效的方案是统一校验命名空间为jakarta.validation,具体步骤如下:
一、彻底清理javax.validation相关依赖
在pom.xml中排除所有引入javax校验的依赖,包括spring-boot-starter-web自带的validation模块:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </exclusion> <exclusion> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> </exclusion> </exclusions> </dependency>
同时执行mvn dependency:tree命令查看依赖树,若其他依赖(包括新增的第三方依赖)引入了javax.validation相关包,也一并通过<exclusion>标签排除。
二、引入Jakarta Validation兼容依赖
添加适配Spring 5.x(SpringBoot2.2基于Spring5.2)的Jakarta校验API与实现:
<!-- Jakarta Validation API --> <dependency> <groupId>jakarta.validation</groupId> <artifactId>jakarta.validation-api</artifactId> <version>3.0.2</version> </dependency> <!-- Hibernate Validator(Jakarta版本,兼容Spring5.x) --> <dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> <version>7.0.5.Final</version> </dependency> <!-- 表达式语言依赖,Hibernate Validator必需 --> <dependency> <groupId>org.glassfish</groupId> <artifactId>jakarta.el</artifactId> <version>4.0.1</version> </dependency>
三、替换代码中的校验导入
将原有代码所有javax.validation开头的导入替换为jakarta.validation,例如:
- 替换
import javax.validation.constraints.NotEmpty;→import jakarta.validation.constraints.NotEmpty; - 替换
import javax.validation.Valid;→import jakarta.validation.Valid;
四、自定义Spring校验器配置
由于SpringBoot2.2默认初始化javax校验器,需手动配置Jakarta版本的校验器:
import jakarta.validation.Validation; import jakarta.validation.Validator; import jakarta.validation.ValidatorFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.support.ResourceBundleMessageSource; import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; @Configuration public class ValidationConfig { @Bean public Validator validator() { ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); return factory.getValidator(); } @Bean public LocalValidatorFactoryBean localValidatorFactoryBean() { LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean(); bean.setValidationMessageSource(messageSource()); bean.setProviderClass(org.hibernate.validator.HibernateValidator.class); return bean; } @Bean public ResourceBundleMessageSource messageSource() { ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); messageSource.setBasename("ValidationMessages"); messageSource.setDefaultEncoding("UTF-8"); return messageSource; } }
备选方案:类加载隔离(仅当无法修改代码时使用)
若不想调整原有代码的校验包结构,可通过Maven Shade插件将新增依赖及其Jakarta校验依赖打包为独立JAR,使用自定义类加载器加载,实现类路径隔离。该方案配置复杂,需熟悉类加载机制,仅作为兜底选项。
关于SpringBoot2.3升级失效的说明
SpringBoot2.3本身仍基于Spring5.x,默认使用javax.validation,升级后若仍引入Jakarta校验依赖,冲突问题不会自动解决。需按照上述方案一的步骤替换为Jakarta校验体系,才能彻底解决冲突。
内容的提问来源于stack exchange,提问作者sushi
相关产品推荐
相关产品推荐

