Bean Validation 官网:beanvalidation.org
hibernate validator 官网:hibernate.org/validator/
spring-boot-starter-validation是Spring Boot对hibernate validator整合。
hibernate validator是 Bean Validation 的具体实现,它提供了一套比较完善、便捷的验证实现方式。
项目中引入Maven依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>hibernate的校验模式:
普通模式(默认):校验所有的属性,然后返回所有的验证失败信息快速失败返回模式:只要有一个验证失败,则返回快速失败校验模式配置如下:
@Bean public Validator validator() { ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class) .configure() //设置validator模式:快速失败返回 //方式一 .failFast(true) //方式二 //.addProperty("hibernate.validator.fail_fast", "true") .buildValidatorFactory(); return validatorFactory.getValidator(); }在resources目录下,创建i18n目录,用于存放国际化配置文件。
再在i18n目录下创建校验提示的Resource Bundle国际化配置文件SystemValidationMessages。
Validation国际化核心配置:
@Bean public LocalValidatorFactoryBean defaultValidator(@Qualifier("validationMessageResource") MessageSource messageSource ) { LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean(); //设置提示消息国际化 localValidatorFactoryBean.setMessageInterpolator(new ResourceBundleMessageInterpolator(new PlatformResourceBundleLocator("i18n/SystemValidationMessages"))); return localValidatorFactoryBean; } @Bean public MethodValidationPostProcessor methodValidationPostProcessor(Environment environment, @Lazy Validator validator) { MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor(); MethodValidationPostProcessor processor = new MethodValidationPostProcessor(); boolean proxyTargetClass = environment.getProperty("spring.aop.proxy-target-class", Boolean.class, true); processor.setProxyTargetClass(proxyTargetClass); processor.setValidator(validator); return postProcessor; }至于为什么要这么配置,从Validation的自动化配置类org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration中可以看出,Spring Boot项目中如何配置自定义的Validaiton处理器。
/** * {@link EnableAutoConfiguration Auto-configuration} to configure the validation * infrastructure. * * @author Stephane Nicoll * @author Madhura Bhave * @since 1.5.0 */ @Configuration(proxyBeanMethods = false) @ConditionalOnClass(ExecutableValidator.class) @ConditionalOnResource(resources = "classpath:META-INF/services/javax.validation.spi.ValidationProvider") @Import(PrimaryDefaultValidatorPostProcessor.class) public class ValidationAutoConfiguration { @Bean @Role(BeanDefinition.ROLE_INFRASTRUCTURE) @ConditionalOnMissingBean(Validator.class) public static LocalValidatorFactoryBean defaultValidator() { LocalValidatorFactoryBean factoryBean = new LocalValidatorFactoryBean(); MessageInterpolatorFactory interpolatorFactory = new MessageInterpolatorFactory(); factoryBean.setMessageInterpolator(interpolatorFactory.getObject()); return factoryBean; } @Bean @ConditionalOnMissingBean public static MethodValidationPostProcessor methodValidationPostProcessor(Environment environment, @Lazy Validator validator) { MethodValidationPostProcessor processor = new MethodValidationPostProcessor(); boolean proxyTargetClass = environment.getProperty("spring.aop.proxy-target-class", Boolean.class, true); processor.setProxyTargetClass(proxyTargetClass); processor.setValidator(validator); return processor; } }一般情况,原生的校验器可以满足业务需求,但也有无法满足情况的时候,此时,可以实现validator的接口,自定义自己需要的验证器。
自定义校验器示例:校验字符串是否包含违禁词。
import javax.validation.Constraint; import javax.validation.Payload; import java.lang.annotation.Documented; import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.*; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * 自定义校验器:校验字符串是否包含违禁词 * * @author wangzhihao */ @Documented @Constraint(validatedBy = {CannotHaveProhibitedWordValidator.class}) @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER}) @Retention(RUNTIME) @Repeatable(CannotHaveProhibitedWord.List.class) public @interface CannotHaveProhibitedWord { //默认错误消息,这里错误信息从国际化配置文件中获取 String message() default "{system.validation.CannotHaveProhibitedWord.message}"; //分组 Class<?>[] groups() default {}; //负载 Class<? extends Payload>[] payload() default {}; //指定多个时使用 @Target({FIELD, METHOD, PARAMETER, ANNOTATION_TYPE}) @Retention(RUNTIME) @Documented @interface List { CannotHaveProhibitedWord[] value(); } }实现ConstraintValidator定义该校验器的约束规则:
/** * 规则:字符串中不能包含违禁词 */ @Slf4j public class CannotHaveProhibitedWordValidator implements ConstraintValidator<CannotHaveProhibitedWord, String> { @Override public void initialize(CannotHaveProhibitedWord constraintAnnotation) { } @Override public boolean isValid(String value, ConstraintValidatorContext context) { //null时不进行校验 if (value == null) { return true; } return !haveProhibitedWord(value); } /** * 是否包含违禁词 * * @param value 校验字符串 * @return 是否包含 */ private boolean haveProhibitedWord(String value) { String[] prohibitedWordArr = {"违禁词1", "违禁词2", "违禁词3"}; for (String prohibitedWord : prohibitedWordArr) { if (value.contains(prohibitedWord)) { return true; } } return false; } }项目Demo:bean-validation
效果图:
