当前位置: 首页 > news >正文

用自定义注解实现Excel数据导入中的枚举值校验

使用自定义注解实现Excel数据导入中的枚举值校验

在实际开发中,我们经常需要从Excel文件中导入数据,并且这些数据需要符合一定的规则,比如某些字段的值必须是预定义的枚举值。本文将介绍如何使用自定义注解来实现这一功能,以提高代码的可维护性和可读性。

1. 定义自定义注解

首先,我们需要定义一个自定义注解FieldEnum,用于标记需要进行枚举值校验的字段。

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 字段枚举信息配置
 *
 * @author liusy
 * @since 2022/05/30 15:57 星期一
 */
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = {ElementType.FIELD, ElementType.PARAMETER})
public @interface FieldEnum {

    /**
     * 枚举类型,从数据库枚举表中校验
     */
    String type() default "";

    /**
     * 是否是组合枚举,多个用,分割
     */
    boolean isEnumGroup() default false;

    /**
     * 设置本地枚举列表,默认为空,如果设置将从本地枚举列表中获取进行对比
     *
     * @return 本地枚举列表
     */
    String[] localEnumList() default {};
}

2. 实现校验逻辑

接下来,我们需要实现一个工具类ValidateUtil,用于校验带有FieldEnum注解的字段。


import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.inspur.planning.flow.annotation.FieldEnum;
import com.inspur.planning.flow.exception.CustomException;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.ValidationException;
import javax.validation.Validator;
import java.lang.reflect.Field;
import java.util.*;

/**
 * @author liusy
 * @since 2023/03/16 14:40 星期四
 */
public class ValidateUtil {

    public static <T> void validateEnum(T bean) {
        List<String> errorMsgList = new ArrayList<>();

        Field[] fields = bean.getClass().getDeclaredFields();

        for (Field field : fields) {
            field.setAccessible(true);

            Object val = getFieldValue(field, bean);
            if (ObjectUtil.isEmpty(val)) {
                continue;
            }

            FieldEnum fieldEnum = field.getAnnotation(FieldEnum.class);
            if (fieldEnum != null) {
                validateFieldEnum(fieldEnum, val, errorMsgList);
            }
        }

        if (!errorMsgList.isEmpty()) {
            throw new CustomException(String.join(";", errorMsgList));
        }
    }

    private static Object getFieldValue(Field field, Object bean) {
        try {
            return field.get(bean);
        } catch (IllegalAccessException e) {
            throw new RuntimeException("反射获取字段值失败", e);
        }
    }

    private static void validateFieldEnum(FieldEnum fieldEnum, Object val, List<String> errorMsgList) {
        String name = val.toString();

        // 本地枚举校验
        if (fieldEnum.localEnumList().length > 0) {
            if (!Arrays.asList(fieldEnum.localEnumList()).contains(name)) {
                errorMsgList.add(name + "不是枚举值,请按照枚举填写");
            }
        }

        if(StrUtil.isNotEmpty(fieldEnum.type())){
            // 数据库查询校验
            if (fieldEnum.isEnumGroup()) {
                String[] split = name.split(",");
                for (String item : split) {
                    if (!checkIsEnum(fieldEnum.type(), item)) {
                        errorMsgList.add(item + "不是枚举值,请按照枚举填写");
                    }
                }
            } else {
                if (!checkIsEnum(fieldEnum.type(), name)) {
                    errorMsgList.add(name + "不是枚举值,请按照枚举填写");
                }
            }
        }

    }

    private static boolean checkIsEnum(String type, String name) {
        JdbcTemplate jdbcTemplate = SpringUtil.getBean(JdbcTemplate.class);
        String sql = "select count(1) from PL_ENUMERATION where TYPE = ? and NAME = ? and STATEFLAG = 0";
        return jdbcTemplate.queryForObject(sql, Integer.class, type, name) > 0;
    }
}

3. 在数据模型中使用注解

在需要进行枚举值校验的字段上添加FieldEnum注解。

@Data
public class ImporTaskDTO {

    /**
     * 任务状态
     */
    @NotEmpty(message = "任务状态不能为空")
    @FieldEnum(localEnumList = {"施工中,未提交完工", "提交送审", "已提交完工未送审"})
    @ExcelProperty("任务状态【必填】")
    private String taskStatus;

    /**
     * 是否有问题
     */
    @FieldEnum(localEnumList = {"是", "否"})
    @NotEmpty(message = "是否有问题不能为空")
    @ExcelProperty("是否有问题【必填】")
    private String existsProblem;


    /**
     * 问题重要程度
     */
	@FieldEnum(type = "PROBLEM_LEVEL", isEnumGroup = false)
	private String problemLevel;


   

    /**
     * 检查方式
     */
    @NotEmpty(message = "检查方式不能为空")
    @ExcelProperty("检查方式【必填】")
    private String checkType;

}

4. 在业务逻辑中调用校验方法

在导入Excel数据的方法中调用ValidateUtil.validateEnum方法进行校验。

    @Override
    public List<QualityManageOrder> analysisExcel(MultipartFile file) {
        List<ImportTaskDTO> dataList = new ArrayList<>();
        try {
            EasyExcel.read(file.getInputStream(), ImportQualityManageTaskDTO.class, new PageReadListener<ImportTaskDTO>(readList -> {
                dataList.addAll(readList);
            })).sheet().doRead();
        } catch (IOException e) {
            throw new CustomException("读取文件失败");
        }
        // 校验数据,并且填充基本任务数据
        ValidateUtil.validateEnum(dataList);

        // 其他业务逻辑...
        return orderList;
    }

通过以上步骤,我们就可以使用自定义注解实现Excel数据导入时的枚举值校验。这样不仅提高了代码的可维护性,还使得代码更加简洁和易读。

相关文章:

  • 第25周JavaSpringboot实战-电商项目 2.数据库准备和项目初始化
  • Dify本地部署过程问题
  • openGauss 6.0.0 RC1数据库日常运维
  • AllData数据中台核心菜单十三:数据湖平台
  • 【大模型】硅基流动对接DeepSeek使用详解
  • Jenkins+maven+gitlab+shell 实现项目自动化部署
  • 聚铭网络入围2025年度江苏省政府采购信息安全设备协议供货名单
  • 汽车通信未来新趋势:Eclipse uProtocol
  • 如何使用DeepSeek + PlantUML/Mermaid 生成专业图表
  • mysql查询判断函数,类似decode
  • SQL 注入攻击详解[基础篇]:Web 应用程序安全漏洞与防御策略
  • 【算法】快排
  • Go 自动升级依赖版本
  • 网络安全“挂图作战“及其场景
  • Go入门之数组与切片
  • 【基础架构篇八】《DeepSeek异构计算:CPU/GPU/TPU协同加速方案》
  • 基于Spring Boot的社区居民健康管理平台的设计与实现
  • 【Vue3】Vue 3 中列表排序的优化技巧
  • Qt的QTabWidget样式设置
  • Python----数据结构(双向链表:节点,是否为空,长度,遍历,添加,删除,查找,循环链表)
  • 怎样建免费网站/怎样推广app别人才愿意下载
  • 网络营销营销型网站建设/百度引流平台
  • 毕业设计做购物网站/输入搜索内容
  • wordpress怎么登陆后台/进一步优化落实
  • 企业平台网站建设/推广app最快的方法
  • 怎么做扫二维码就可以进入网站/最近一周的热点新闻