每篇一句
NBA里有两大笑话:一是科比没天赋,二是詹姆斯没技术
相关阅读
【小家Java】深入了解数据校验:Java Bean Validation 2.0(JSR303、JSR349、JSR380)Hibernate-Validation 6.x使用案例
【小家Spring】让Controller支持对平铺参数执行数据校验(默认Spring MVC使用@Valid只能对JavaBean进行校验)
【小家Spring】Spring方法级别数据校验:@Validated + MethodValidationPostProcessor优雅的完成数据校验动作
前言
关于Bean Validation
的基本原理篇完结之后,接下来就是小伙伴最为关心的干货:使用篇。
如果说要使用Bean Validation
数据校验,我十分相信小伙伴们都能够使用,但估计大都是有个前提的:Spring MVC
环境。我极其简单的调查了一下,近乎99%
的人都是只把数据校验使用在Spring MVC
的Controller
层面的,而且几乎90%
的人都是让它必须和@RequestBody
一起来使用去校验JavaBean
入参~
如果这么去理解Bean Validation
的使用,那就有点太过于片面了,毕竟被Spring包裹起来,你其实很难去知道它真正做的事。
熟悉我文章风格的人知道,每篇文章我都会带你领略一些不一样的风景,本章亦不例外,会让你知道数据校验在Spring
框架之外的一些事~
分组校验
在我的前置原理篇文章,分组校验其实是没太大必要说的,因为使用起来确实非常的简单。此处还是给个分组校验的使用案例吧:
@Getter
@Setter
@ToString
public class Person {
// 错误消息message是可以自定义的
@NotNull(message = "{message} -> 名字不能为null", groups = Simple.class)
public String name;
@Max(value = 10, groups = Simple.class)
@Positive(groups = Default.class) // 内置的分组:default
public Integer age;
@NotNull(groups = Complex.class)
@NotEmpty(groups = Complex.class)
private List<@Email String> emails;
@Future(groups = Complex.class)
private Date start;
// 定义两个组 Simple组和Complex组
interface Simple {
}
interface Complex {
}
}
执行分组校验:
public static void main(String[] args) {
Person person = new Person();
//person.setName("fsx");
person.setAge(18);
// email校验:虽然是List都可以校验哦
person.setEmails(Arrays.asList("fsx@gmail.com", "baidu@baidu.com", "aaa.com"));
//person.setStart(new Date()); //start 需要是一个将来的时间: Sun Jul 21 10:45:03 CST 2019
//person.setStart(new Date(System.currentTimeMillis() + 10000)); //校验通过
Hibernateva lidatorConfiguration configure = Validation.byProvider(Hibernateva lidator.class).configure();
ValidatorFactory validatorFactory = configure.failFast(false).buildValidatorFactory();
// 根据validatorFactory拿到一个Validator
Validator validator = validatorFactory.getValidator();
// 分组校验(可以区分对待Default组、Simple组、Complex组)
Set<ConstraintViolation<Person>> result = validator.validate(person, Person.Simple.class);
//Set<ConstraintViolation<Person>> result = validator.validate(person, Person.Complex.class);
// 对结果进行遍历输出
result.stream().map(v -> v.getPropertyPath() + " " + v.getMessage() + ": " + v.getInvalidValue())
.forEach(System.out::println);
}
运行打印:
age 最大不能超过10: 18
name {message} -> 名字不能为null -> 名字不能为null: null
可以直观的看到效果,此处的校验只执行Person.Simple.class
这个Group
组上的约束~
分组约束在Spring MVC中的使用场景还是相对比较多的,但是需要注意的是:
javax.validation.Valid
没有提供指定分组的,但是org.springframework.validation.annotation.Validated
扩展提供了直接在注解层面指定分组的能力
@Valid注解
我们知道JSR
提供了一个@Valid
注解供以使用,在本文之前,绝大多数小伙伴都是在Controller
中并且结合@RequestBody
一起来使用它,但在本文之后,你定会对它有个全新的认识~
==该注解用于验证级联的属性、方法参数或方法返回类型。==
当验证属性、方法参数或方法返回类型时,将验证对象及其属性上定义的约束,另外:此行为是递归应用的。
:::为了理解@Valid
,那就得知道处理它的时机:::
MetaDataProvider
元数据提供者:约束相关元数据(如约束、默认组序列等)的Provider
。它的作用和特点如下:
- 基于不同的元数据:如xml、注解。(还有个编程映射) 这三种类型。对应的枚举类为:
public enum ConfigurationSource {
ANNOTATION( 0 ),
XML( 1 ),
API( 2 ); //programmatic API
}
MetaDataProvider
只返回直接为一个类配置的元数据- 它不处理从超类、接口合并的元数据(
简单的说你@Valid放在接