数据字典与枚举类的结合使用,并通过自定义注解来对传入数据字典进行校验

思路:前端传来字典值,例下面这个字典:

public enum CO00001 {

    YES("Y", "是"),
    NO("N", "否");

    private final String value;
    private final String label;

    CO00001(String value, String label) {
        this.value = value;
        this.label = label;
    }

    public String getValue() {
        return value;
    }

    public String getText() {
        return label;
    }
}

前端会传来一个值,比如是“Y”,那么我们需要对这个“Y”进行校验,判断是否这个“Y”是我们的字典值,由于字典值一般是在开发阶段前就会定好的,所以我们可以把字典值以枚举的形式进行创建,之后我们用传进来的值与我们创建好的枚举值进行校验,但是如果采用编码的方式的话,一个接口就要写一遍,而且不用的字典还要写不用的校验,所以这里采用自定义注解的形式来实现对接口中字段的校验

  1. 创建自定义注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 1. @author mr.ahai
 2. 自定义字典校验
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Idict {
    Class<?> code();
}
  1. 注解的切面处理
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.jeecg.common.exception.DictException;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 1. @author mr.ahai
 2. 自定义字典统一且切面处理
 */
@Aspect
@Component
@Slf4j
public class IdictAspect {


    /**
     * 仅对org.jeecg.modules.fieldmanage.controller.TbFieldManagerController 下的所有方法进行拦截处理
     * 全局生效时:请修改该切面
     */
    @Pointcut("execution(public * org.jeecg.modules.fieldmanage.controller.TbFieldManagerController.*(..))")
    public void idict() {
    }

    /**
     * 对字典值进行校验
     *
     * @param pjp 固定写法,用来获取字典传入的值
     * @return 返回该数据的值
     */
    @Around("idict()")
    public Object dictionaryConversion(ProceedingJoinPoint pjp) throws Throwable {
        // pjp.proceed方法在before方法执行后执行
        Object result = pjp.proceed();
        log.info("在后执行");
        return result;
    }

    /**
     * 执行注解之前前
     *
     * @param joinPoint
     * @throws Throwable
     */
    @Before("idict()")
    public void before(JoinPoint joinPoint) throws Exception {
        // 入参数的DTO
        Object arg = joinPoint.getArgs()[0];
        Class<?> clazz = arg.getClass();
        for (Field field : clazz.getDeclaredFields()) {
            // 如果字段上存在Idict字典
            if (field.isAnnotationPresent(Idict.class)) {
                // 获取字段的值
                field.setAccessible(true);
                // 如果传来的是空,可能是查询,直接跳过验证,必填校验通过NotNull 注解来校验
                if (Objects.isNull(field.get(arg))) {
                    break;
                }
                // 如果是字典的话,查看一下映射的字典是否正确
                String dictValue = field.get(arg).toString();
                // 获取字典上方标记的数据字典类
                Class<?> code = field.getAnnotation(Idict.class).code();
                Method getCode = code.getMethod("getValue");
                Object[] enumConstants = code.getEnumConstants();
                List<String> yValueList = new ArrayList<>();
                for (Object dict : enumConstants) {
                    String yValue = getCode.invoke(dict).toString();
                    yValueList.add(yValue);
                }
                if (!yValueList.contains(dictValue)) {
                    throw new DictException("报错了报错了!!!!!");
                }
            }
        }
    }
}
  1. 使用方式:

数据字典与枚举类的结合使用,并通过自定义注解来对传入数据字典进行校验_第1张图片

你可能感兴趣的:(java,spring)