Spring Boot低版本Hibernate Validator下如何为Javax内置NotBlank注解自定义校验逻辑
Spring Boot低版本Hibernate Validator下如何为Javax内置NotBlank注解自定义校验逻辑
我太懂这种被老版本依赖卡脖子的感觉了!之前维护老项目的时候也碰到过Hibernate Validator 5.x和Javax校验注解冲突的坑,给你分享个亲测有效的解决方案,不用升级依赖也能让javax的NotBlank正常生效。
核心思路
问题根源是Hibernate Validator 5.x里自带了org.hibernate.validator.constraints.NotBlank注解,它的优先级会覆盖Javax的javax.validation.constraints.NotBlank,导致你的校验逻辑不触发。我们要做的就是给Javax的NotBlank注解绑定自定义的校验器,并让Hibernate Validator优先使用这个校验器。
步骤1:编写自定义Javax NotBlank校验器
先写一个实现了ConstraintValidator的校验类,专门处理Javax的NotBlank注解:
import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import javax.validation.constraints.NotBlank; public class JavaxNotBlankValidator implements ConstraintValidator<NotBlank, CharSequence> { @Override public void initialize(NotBlank constraintAnnotation) { // 这里不需要额外初始化操作,留空即可 } @Override public boolean isValid(CharSequence value, ConstraintValidatorContext context) { // 校验逻辑:不为null,且trim后长度大于0 if (value == null) { return false; } return value.toString().trim().length() > 0; } }
步骤2:绑定校验器到Javax NotBlank注解
有两种方式可以完成绑定,选一种你觉得顺手的就行:
方式A:使用XML配置文件(更直观)
- 在
src/main/resources/META-INF下创建validation.xml,指定我们的约束映射文件:
<?xml version="1.0" encoding="UTF-8"?> <validation-config xmlns="http://jboss.org/xml/ns/javax/validation/configuration" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/configuration http://jboss.org/xml/ns/javax/validation/configuration/validation-config-1.1.xsd" version="1.1"> <constraint-mapping>META-INF/javax-notblank-mapping.xml</constraint-mapping> </validation-config>
- 同样在
META-INF下创建javax-notblank-mapping.xml,把Javax的NotBlank和我们的校验器绑定,关键要加上include-existing-validators="false",强制覆盖默认校验器:
<?xml version="1.0" encoding="UTF-8"?> <constraint-mappings xmlns="http://jboss.org/xml/ns/javax/validation/mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/mapping http://jboss.org/xml/ns/javax/validation/mapping/validation-mapping-1.1.xsd" version="1.1"> <constraint-definition annotation="javax.validation.constraints.NotBlank"> <validated-by include-existing-validators="false"> <value>com.yourproject.validator.JavaxNotBlankValidator</value> </validated-by> </constraint-definition> </constraint-mappings>
注意把com.yourproject.validator换成你实际的校验器包路径。
方式B:Java代码配置(无需XML)
如果不想写XML,可以通过Spring的配置类直接注册校验器:
import org.hibernate.validator.HibernateValidatorConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; import javax.validation.ConstraintMapping; import javax.validation.Validator; @Configuration public class ValidatorConfig { @Bean public Validator validator() { LocalValidatorFactoryBean factoryBean = new LocalValidatorFactoryBean(); factoryBean.setValidationInitializer(config -> { HibernateValidatorConfiguration hibernateConfig = (HibernateValidatorConfiguration) config; ConstraintMapping mapping = hibernateConfig.createConstraintMapping(); // 绑定Javax NotBlank到自定义校验器,同时禁用原有校验器 mapping.constraintDefinition(javax.validation.constraints.NotBlank.class) .validatedBy(JavaxNotBlankValidator.class) .includeExistingValidators(false); hibernateConfig.addMapping(mapping); }); return factoryBean; } }
关键注意事项
- 必须加
include-existing-validators="false":这是核心,不然Hibernate Validator还是会优先使用自带的NotBlank校验逻辑,我们的自定义代码就白写了。 - 校验器的泛型要对应:
ConstraintValidator<NotBlank, CharSequence>里的第二个泛型是CharSequence,因为NotBlank注解作用在String等字符序列类型上,别写错了。 - 测试验证:写完后可以写个简单的测试类,注入
javax.validation.Validator,用它来校验带有@NotBlank的实体,看看是否触发了我们的校验逻辑。
按照这个流程走,就能让Javax的NotBlank注解在Hibernate Validator 5.1.0.Final下正常工作了,我之前在同版本的项目上试过,完全没问题。
内容来源于stack exchange
相关产品推荐
相关产品推荐

