hibernate validate分组校验"/>
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对应字段了。
更多推荐
hibernate validate分组校验
发布评论