设为首页 加入收藏

TOP

从深处去掌握数据校验@Valid的作用(级联校验)(一)
2019-09-01 23:49:05 】 浏览:51
Tags:深处 掌握 数据 校验 @Valid 作用

每篇一句

NBA里有两大笑话:一是科比没天赋,二是詹姆斯没技术

相关阅读

【小家Java】深入了解数据校验:Java Bean Validation 2.0(JSR303、JSR349、JSR380)Hibernate-Validation 6.x使用案例
【小家Spring】让Controller支持对平铺参数执行数据校验(默认Spring MVC使用@Valid只能对JavaBean进行校验)
【小家Spring】Spring方法级别数据校验:@Validated + MethodValidationPostProcessor优雅的完成数据校验动作


对Spring感兴趣可扫码加入wx群:`Java高工、架构师3群`(文末有二维码)

前言

关于Bean Validation的基本原理篇完结之后,接下来就是小伙伴最为关心的干货:使用篇
如果说要使用Bean Validation数据校验,我十分相信小伙伴们都能够使用,但估计大都是有个前提的:Spring MVC环境。我极其简单的调查了一下,近乎99%的人都是只把数据校验使用在Spring MVCController层面的,而且几乎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。它的作用和特点如下:

  1. 基于不同的元数据:如xml、注解。(还有个编程映射) 这三种类型。对应的枚举类为:
public enum ConfigurationSource {
    ANNOTATION( 0 ),
    XML( 1 ),
    API( 2 ); //programmatic API
}
  1. MetaDataProvider只返回直接为一个类配置的元数据
  2. 它不处理从超类、接口合并的元数据(简单的说你@Valid放在接
首页 上一页 1 2 3 4 5 下一页 尾页 1/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇jdk1.8 HashMap底层数据结构:散.. 下一篇基于Morphia实现MongoDB按小时、..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目