1 前言
在进行数据验证的过程中,我们可能会遇到这样的情况:
由于数据库中,存在着历史数据,历史数据并不一定遵循了我们之前添加的数据验证的规范。这时,我们需要将新增和修改分为两种不同的情况来处理。
又或者,对于同一类数据(这里指数据表相同),但是要分为不同的类型处理
比如存在这一个员工表,A类员工的部分信息是必须要检查的,B类员工的部分信息是必须要检查的。员工表设计的是一个冗余的表结构。这时候,对两类员工也可能要分组进行验证处理。
那么,接下来,介绍如何使用hibernate-validator进行分组验证。使用分组验证有两种方式,一种是以声明时注解,另一种是调用Validator.validate方法判断。
2 采用声明式注解的方式
(1) 先定义使用的类
这里先定义了一个员工表,以及员工月薪表。
Employee类:
package cn.iocoder.springboot.lab22.ex.validation.domain;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import javax.validation.Valid;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Past;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.NotEmpty;
import java.util.Date;
/**
* 员工信息
* @author galen
* @date 2020/2/26
* */
@Data
public class Employee {
public interface AGroup{}
public interface BGroup{}
@NotEmpty(groups = AGroup.class,message = "姓名必填!")
@Length(max = 20, message = "姓名过长!")
private String name;
@NotEmpty(groups = BGroup.class,message = "工牌必填!")
/*@Pattern(regexp = "^\\d{10}",message = "请输入10位数字工牌!")//长度10,0-9*/
private String badgeCode;
@Pattern(regexp = "^[1-2]",message = "性别参数错误!")
@NotNull(message = "性别必填!")
private String gender;
@Past(message = "无效的出生日期!")
private Date birthDate;
@Email
private String email;
@NotNull(message = "身份证号码必填!")
@Pattern(regexp = "^[1-9]\\d{5}(18|19|([23]\\d))\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$"
,message = "身份证号码格式错误")
private String idCardNumber;
@Valid
private Salary salary;
@NotNull(message = "联系电话必填!")
@Pattern(regexp = "^[1]+\\d{10}$"
,message = "电话号码格式错误")
private String phoneNumber;
@Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
", badgeCode='" + badgeCode + '\'' +
", gender=" + gender +
", birthDate=" + birthDate +
'}';
}
}
Salary类:
package cn.iocoder.springboot.lab22.ex.validation.domain;
import lombok.Data;
import javax.validation.constraints.NotNull;
@Data
public class Salary {
@NotNull(message = "月份必填!")
private int month;
@NotNull(message = "年份必填!")
private int year;
@NotNull(message = "薪金必填!")
private int money;
@NotNull(message = "员工姓名必填!")
private String name;
}
(2) 调用方式
@PostMapping("/addEmployeeByAnnotationGroup")
public Object addEmployeeByAnnotationGroup(@Validated(Employee.AGroup.class) @RequestBody Employee employee1){
return "添加职员信息成功" ;
}
调试结果
调用时,只会验证 name 字段 。
3 采用Api调用的方式
(1) 注册bean, Validator 对象
package cn.iocoder.springboot.lab22.ex.validation.config;
import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import javax.validation.Validator;
@Configuration
public class ValidationConfiguration {
/**
* 参考 {@link ValidationAutoConfiguration#defaultValidator()} 方法,构建 Validator Bean
*
* @return Validator 对象
*/
@Bean
public Validator validator(MessageSource messageSource) {
// 创建 LocalValidatorFactoryBean 对象
LocalValidatorFactoryBean validator = ValidationAutoConfiguration.defaultValidator();
// 返回
return validator;
}
}
(2) 手动验证
/**
* 使用分组验证,在数据传入前,不做判断(没有加任何声明式注解),然后根据条件,采用不同的数据验证方式
* */
@PostMapping("/addEmployeeByGroup")
public Object addEmployeeByGroup(@RequestBody Employee employee1){
String validateResult = validateUserByGroup(employee1,"1");
return validateResult.isEmpty()==true?"添加职员信息成功" :validateResult;
}
/**
* 根据userid,进行条件判断,采用不同的数据验证方式
* */
public String validateUserByGroup(Employee employee1, String userId){
//这里根据传入的userid,来选择不同的分组。省略了此处代码
//验证AGroup(约束设置为AGroup),得到校验结果信息 Set
Set<ConstraintViolation<Employee>> constraintViolationSet1 = validator.validate(employee1,Employee.AGroup.class);
//验证BGroup(约束设置为BGroup),得到校验结果信息 Set
Set<ConstraintViolation<Employee>> constraintViolationSet2 = validator.validate(employee1,Employee.BGroup.class);
//验证默认约束项(未添加group),得到校验结果信息 Set
Set<ConstraintViolation<Employee>> constraintViolationSet3 = validator.validate(employee1);
//StringBuilder组装异常信息
StringBuilder builder = new StringBuilder();
//遍历拼装
constraintViolationSet1.forEach(violationInfo -> {
builder.append(violationInfo.getMessage() + lineSeparator);
});
constraintViolationSet2.forEach(violationInfo -> {
builder.append(violationInfo.getMessage() + lineSeparator);
});
constraintViolationSet3.forEach(violationInfo -> {
builder.append(violationInfo.getMessage() + lineSeparator);
});
if (builder.toString().length() > 0){
builder.insert(0,"use validator :" +lineSeparator);
return builder.toString();
}
return "";
}