EasyExcel validator校验 及自定义 枚举校验

发布时间 2023-06-30 16:21:17作者: 倔强的老铁

需要校验的实体

import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.ruoyi.system.domain.enums.RoleStatusEnum;
import com.ruoyi.system.domain.enums.YesOrNoEnum;
import com.ruoyi.system.domain.export.BaseExportData;
import com.ruoyi.system.domain.vo.role.SysRoleVO;
import com.ruoyi.system.service.imports.valid.EnumValid;
import org.hibernate.validator.constraints.Range;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;

/**
 * 角色导出数据类
 * @author ruoyi
 **/
public class RoleExcelData extends BaseExportData {

    @NotBlank(message = "不可空")
    @Range(min = 1, message = "应为正整数且小于19位")
    @ColumnWidth(20)
    @ExcelProperty("角色ID")
    private String roleId;

    @Size(max = 30, message = "不大于30位字符")
    @NotBlank(message = "不可空")
    @ColumnWidth(20)
    @ExcelProperty("角色名称")
    private String roleName;

    @Size(max = 100, message = "不大于100位字符")
    @NotBlank(message = "不可空")
    @ColumnWidth(20)
    @ExcelProperty("权限字符")
    private String roleKey;

    @NotBlank(message = "不可空")
    @Range(min = 0, max = 9999, message = "不大于9999自然数")
    @ColumnWidth(20)
    @ExcelProperty("角色排序")
    private String roleSort;

    @NotBlank(message = "不可空")
    @EnumValid(value = YesOrNoEnum.class, method2 = "getName", message = "值不正确,[是, 否, 1, 0]中的一个值")
    @ColumnWidth(20)
    @ExcelProperty("控制台权限")
    private String unimisFlag;

    @NotBlank(message = "不可空")
    @ColumnWidth(20)
    @ExcelProperty("数据权限")
    private String dataScope;

    @NotBlank(message = "不可空")
    @EnumValid(value = RoleStatusEnum.class, method2 = "getName", message = "值不正确,[正常, 停用, 0, 1]中的一个值")
    @ColumnWidth(20)
    @ExcelProperty("角色状态")
    private String status;

    @NotBlank(message = "不可空")
    @ColumnWidth(20)
    @ExcelProperty("应用ID")
    private String appId;

    @EnumValid(value = YesOrNoEnum.class, method2 = "getName", message = "值不正确,[是, 否, 1, 0]中的一个值")
    @NotBlank(message = "不可空")
    @ColumnWidth(20)
    @ExcelProperty("默认角色标志")
    private String defaultFlag;

    @EnumValid(value = YesOrNoEnum.class, method2 = "getName", message = "值不正确,[是, 否, 1, 0]中的一个值")
    @NotBlank(message = "不可空")
    @ColumnWidth(20)
    @ExcelProperty("用户授权使用")
    private String allowBindingUser;

    @EnumValid(value = YesOrNoEnum.class, method2 = "getName", message = "值不正确,[是, 否, 1, 0]中的一个值")
    @NotBlank(message = "不可空")
    @ColumnWidth(20)
    @ExcelProperty("角色组授权使用")
    private String allowBindingRoleGroup;

    @ColumnWidth(30)
    @ExcelProperty("字段级权限备注")
    private String filedPermsRemark;

    @ExcelProperty("错误描述")
    private String error;

    @ExcelIgnore
    private SysRoleVO vo;

    public String getRoleId() {
        return roleId;
    }

    public void setRoleId(String roleId) {
        this.roleId = roleId;
    }

    public String getRoleName() {
        return roleName;
    }

    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }

    public String getRoleKey() {
        return roleKey;
    }

    public void setRoleKey(String roleKey) {
        this.roleKey = roleKey;
    }

    public String getRoleSort() {
        return roleSort;
    }

    public void setRoleSort(String roleSort) {
        this.roleSort = roleSort;
    }

    public String getUnimisFlag() {
        return unimisFlag;
    }

    public void setUnimisFlag(String unimisFlag) {
        this.unimisFlag = unimisFlag;
    }

    public String getDataScope() {
        return dataScope;
    }

    public void setDataScope(String dataScope) {
        this.dataScope = dataScope;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getAppId() {
        return appId;
    }

    public void setAppId(String appId) {
        this.appId = appId;
    }

    public String getDefaultFlag() {
        return defaultFlag;
    }

    public void setDefaultFlag(String defaultFlag) {
        this.defaultFlag = defaultFlag;
    }

    public String getAllowBindingUser() {
        return allowBindingUser;
    }

    public void setAllowBindingUser(String allowBindingUser) {
        this.allowBindingUser = allowBindingUser;
    }

    public String getAllowBindingRoleGroup() {
        return allowBindingRoleGroup;
    }

    public void setAllowBindingRoleGroup(String allowBindingRoleGroup) {
        this.allowBindingRoleGroup = allowBindingRoleGroup;
    }

    public String getFiledPermsRemark() {
        return filedPermsRemark;
    }

    public void setFiledPermsRemark(String filedPermsRemark) {
        this.filedPermsRemark = filedPermsRemark;
    }

    public String getError() {
        return error;
    }

    public void setError(String error) {
        this.error = error;
    }

    public SysRoleVO getVo() {
        return vo;
    }

    public void setVo(SysRoleVO vo) {
        this.vo = vo;
    }
}

调用位置

for (int i = 0; i < excelData.size(); i++) {
    RoleExcelData row = excelData.get(i);
    String errorMsg = EasyExcelValidHelper.validateEntity(row);
    row.setError(errorMsg);
}

枚举注解

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;

/**
 * @description :校验枚举注解
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD})
@Constraint(validatedBy = EnumValidator.class)
public @interface EnumValid {
    /**
     * 枚举的类型
     */
    Class<?> value();

    /**
     * 错误消息
     *
     * @return
     */
    String message() default "枚举类型的值不正确";

    /**
     * 获取枚举值的方法
     */
    String method() default "getCode";

    String method2() default "";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

枚举具体验证类

import com.ruoyi.common.core.utils.bean.BeanUtils;
import org.apache.commons.compress.utils.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;

/**
 * @description :枚举验证
 */
public class EnumValidator implements ConstraintValidator<EnumValid, Object> {

    private static final Logger logger = LoggerFactory.getLogger(EnumValidator.class);

    /**
     * 存具体枚举的值
     */
    private final List<Object> values = Lists.newArrayList();

    @Override
    public void initialize(EnumValid constraintAnnotation) {

        Class<?> enumClazz = constraintAnnotation.value();
        Object[] enumConstants = enumClazz.getEnumConstants();
        if (null == enumConstants) {
            return;
        }
        Method method = BeanUtils.findMethod(enumClazz, constraintAnnotation.method());
        if (null == method) {
            logger.warn("枚举对象:[{}]中不存在方法:[{}],请检查.", enumClazz.getName(), constraintAnnotation.method());
            throw new RuntimeException("枚举对象中不存在获取值的方法");
        }

        method.setAccessible(true);
        try {
            for (Object enumConstant : enumConstants) {
                values.add(method.invoke(enumConstant));
            }
        } catch (IllegalAccessException | InvocationTargetException e) {
            logger.warn("获取枚举类:[{}]的枚举对象的值失败.", enumClazz);
            throw new RuntimeException("获取枚举值失败");
        }

        Method method2 = BeanUtils.findMethod(enumClazz, constraintAnnotation.method2());
        if (null != method2) {
            try {
                for (Object enumConstant : enumConstants) {
                    values.add(method2.invoke(enumConstant));
                }
            } catch (IllegalAccessException | InvocationTargetException e) {
                logger.warn("获取枚举类:[{}]的枚举对象的值失败.", enumClazz);
                throw new RuntimeException("获取枚举值失败");
            }
        }
    }

    @Override
    public boolean isValid(Object value, ConstraintValidatorContext context) {
        return null == value || values.contains(value);
    }
}

校验工具类

import com.alibaba.excel.annotation.ExcelProperty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.groups.Default;
import java.lang.reflect.Field;
import java.util.Set;

/**
 * @description :校验工具
 */
public class EasyExcelValidHelper {

    private static final Logger logger = LoggerFactory.getLogger(EasyExcelValidHelper.class);

    private EasyExcelValidHelper() {
    }

    /**
     * 校验常量
     */
    private static final Validator VALIDATOR = Validation.buildDefaultValidatorFactory().getValidator();

    /**
     * description 对象校验
     *
     * @param entity 导入数据
     * @return java.lang.String
     **/
    public static <T> String validateEntity(T entity) {
        StringBuilder result = null;
        try {
            result = new StringBuilder();
            Set<ConstraintViolation<T>> set = VALIDATOR.validate(entity, Default.class);
            if (set != null && !set.isEmpty()) {
                for (ConstraintViolation<T> cv : set) {
                    Field declaredField = entity.getClass().getDeclaredField(cv.getPropertyPath().toString());
                    ExcelProperty annotation = declaredField.getAnnotation(ExcelProperty.class);
                    result.append(annotation.value()[0]).append(cv.getMessage()).append("; ");
                }
            }
        } catch (NoSuchFieldException e) {
            logger.error("参数验证异常", e);
        }
        return result.toString();
    }
}