【BeanValidation】二、springboot项目实现分组数据验证

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 "";
    }

在这里插入图片描述

4 源码

源码参考:lab-22,lab22-ex-validation-01

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值