hibernate validate分组校验

我在hibernate validate基本示例即自定义验证使用中已经简单举例说明了hibernate validate的基本使用。但日常系统中对于不同模块可能对于同一字段合法性校验也会不同,例如用户(User)在注册时可能对于是否邮件填写敏感,而用户添加课程学习列表时也只对用户当前添加课程关心,这样我们之前统一的校验就不起作用了,而hibernate提供的分组功能就能帮助我们实现.直接上代码。

public class User {
    @NotBlank(message = "用户名不能为空",groups = FirstGroup.class)
    private String userName;
    @NotBlank(message = "密码不能为空",groups = FirstGroup.class)
    @Size(min = 6, max = 16,message = "密码需在{min}到{max}之间",groups = FirstGroup.class)
    private String password;
    @Min(1)
    @Max(120)
    private Integer age;
    @Email(regexp = "^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*\\.[a-zA-Z0-9]{2,6}$", message =  "邮件格式错误",groups = FirstGroup.class)
    private String email;
    @Size(min = 11, max = 11)
    private String mobile;
    //是否VIP 0否 1是 空默认否
    private Integer vipFlag;
    //VIP授权码 vipFlag为是必填
    private String vipLicenseKey;
    //学习科目
    @ListGtOne(message = "用户学习科目至少为2",groups = SecondGroup.class)
    List<Subject> subjectList;
   }
                      /**对应get、set方法**/

我们只看email和subjectList字段即可,他们对应的group分别是FirstGroup.class,SecondGroup.class,这两个都是接口,名称随便定义也不需要实现,只是能做区分分组就行;当然不写时它会有个默认的分组Default.class,所有不填写的都会划入这个分组。

package com.yh.tbb.hibernate.validate.group;

public interface FirstGroup {
}

对于FirstGroup.class举个例子,上面是我定义的接口。下面是对应的测试类

package com.yh.tbb.hibernate.validate;

import com.yh.tbb.hibernate.validate.domain.Subject;
import com.yh.tbb.hibernate.validate.domain.User;
import com.yh.tbb.hibernate.validate.group.FirstGroup;
import com.yh.tbb.hibernate.validate.group.SecondGroup;
import com.yh.tbb.hibernate.validate.util.ValidateUtil;

import javax.validation.ConstraintViolation;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

public class Test {


    public static void main(String args[]) {
        User user = new User();
        user.setUserName("zhao");
        user.setPassword("123456");
        user.setEmail("123456@qq.@com");
        List<Subject> subjectList = new ArrayList<Subject>();
        Subject subject = new Subject();
        subject.setSubjectCode("A001");
        subjectList.add(subject);
        user.setSubjectList(subjectList);
        Set<ConstraintViolation<User>> result = ValidateUtil.validate(user,FirstGroup.class);
        // 抛出检验异常
        if (result.size() > 0) {
            Iterator<ConstraintViolation<User>> it = result.iterator();
            while (it.hasNext()) {
                ConstraintViolation<User> str = it.next();
                System.out.println(str.getMessage() + "\n");
            }
        }
    }
}

注:ValidateUtil工具类可去我最上面的链接文章查找,这里不再写!
代码校验ValidateUtil.validate(user,FirstGroup.class);加了分组FirstGroup(),这样虽然subjectList的长度不满足条件但也不会校验。
结果:
在这里插入图片描述
注:validate方法FirstGroup.class不传时会调用默认的Default.class分组,当然validate也可以传多个分组,例:ValidateUtil.validate(user,FirstGroup.class,SecondGroup.class),这样
添加这两个分组注释的字段会都校验。
2.
还有一个问题是关于分组优先级,例如当用户还没有用户名密码时,对于用户所学科目列表是多余的,要保证用户存在时再查询学习科目。有童鞋可能会考虑用上面的ValidateUtil.validate(user,FirstGroup.class,SecondGroup.class)方法,但是此方法不一定按照分组入参顺序输出,即便通过Set<ConstraintViolation> result = ValidateUtil.validate(user,FirstGroup.class);返回set我们也可以看出。
hibernate validate注释GroupSequence可以满足我们的需求,定义到类级别上。

@GroupSequence({FirstGroup.class,SecondGroup.class,User.class})
public class User {
    @NotBlank(message = "用户名不能为空",groups = FirstGroup.class)
    private String userName;
    @NotBlank(message = "密码不能为空",groups = FirstGroup.class)
    @Size(min = 6, max = 16,message = "密码需在{min}到{max}之间",groups = FirstGroup.class)
    private String password;
    @Min(1)
    @Max(120)
    private Integer age;
    @Email(regexp = "^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*\\.[a-zA-Z0-9]{2,6}$", message =  "邮件格式错误",groups = FirstGroup.class)
    private String email;
    @Size(min = 11, max = 11)
    private String mobile;
    //是否VIP 0否 1是 空默认否
    private Integer vipFlag;
    //VIP授权码 vipFlag为是必填
    private String vipLicenseKey;
    //学习科目
    @ListGtOne(message = "用户学习科目至少为2",groups = SecondGroup.class)
    List<Subject> subjectList;
   }
                      /**对应get、set方法**/

@GroupSequence({FirstGroup.class,SecondGroup.class,User.class})表示分组由高到低输出顺序,如果这个校验组序列中有一个约束条件没有通过验证的话, 那么此约束条件后面的都不会再继续被校验了.所以加了这个注释后首先就会校验用户信息,FirstGroup存在未通过子段就不会显示SecondGroup错误信息。
注:在这需要注意一下当类中加入GroupSequence时,ValidateUtil.validate(user)调用时此时不会只调用Default.class分组校验,而是按照GroupSequence里面分组优先级进行校验,但是如果自定义了分组那也只按照分组校验,例ValidateUtil.validate(user,SecondGroup.class),这样只能校验SecondGroup.class对应字段了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值