15212562657 发表于 2023-7-27 17:24

多级校验入参Vo校验注解

public enum SubmitCheckEnum {

    NATURAL_PERSON("1", "自然人"),
    LEGAL_PERSON( "2","法人"),
    ;

    @EnumValue
    private final String code;
    private final String desc;

    SubmitCheckEnum(String code, String desc) {
      this.code = code;
      this.desc = desc;
    }

    /**
   * 提前判断,用于解决
   * Case中出现的Constant expression required
   * @Param code
   * @return
   */
    public static List<SubmitCheckEnum> getByCode(String code){
      List<SubmitCheckEnum> enums=new ArrayList<>();
      for(SubmitCheckEnum x:values()){
            if(x.getCode().equals(code)){
                enums.add(x);
            }
      }
      return enums;
    }

    /**
   * 转换器会根据该注解指定的字段转换
   *
   * @Return int
   */
    @JsonValue
    public String getCode() {
      return code;
    }

    public String getDesc() {
      return desc;
    }
}

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SubmitCheck {

    //校验类型 根据code会进行筛选
    SubmitCheckEnum[] checkArray();

    //校验依据字段
    String checkField();
}

public class SubmitCheckUtils {

    static Logger log = LoggerFactory.getLogger(SubmitCheckUtils.class);

    private final static Stack<String> FIELDS_NAME_LISTS =new Stack<>();

    public static<T> void checkData(T t){
      Map map = JSON.parseObject(JSON.toJSONString(t), Map.class);
      Class<?> c = t.getClass();
      List<Field> fields = Arrays.asList(ReflectUtil.getFields(c));
      fields.forEach(f->{
            Boolean flag=Boolean.TRUE;
            //判断是否包含@SubmitCheck 并且判断 SubmitCheck注解的值是不是vo字段
            if (ObjectUtil.isNotEmpty(f.getAnnotation(SubmitCheck.class))) {
                if (!ReflectUtil.hasField(c, f.getAnnotation(SubmitCheck.class).checkField())) {
                  throw new BusinessException(
                            f.getName() + "字段@SubmitCheck注解配置参数checkField[" +
                                    f.getAnnotation(SubmitCheck.class).checkField() + 无效",
                            CommonMessageCode.FAIL.getMsgCode());
                }
                //判断入参中需要区分的校验值是否为空
                if (ObjectUtil.isEmpty(map.get(f.getAnnotation(SubmitCheck.class).checkField()))) {
                  checkSuperFieldIsEmpty(map, f, c);
                  final int size = FIELDS_NAME_LISTS.size();
                  for (int i = 0; i < size; i++) {
                        Field superField = ReflectUtil.getField(c, FIELDS_NAME_LISTS.pop());
                        Object fieldData = map.get(superField.getAnnotation(SubmitCheck.class).checkField());
                        if (ObjectUtil.isEmpty(fieldData)) {
                            Field supField = ReflectUtil.getField(c, superField.getAnnotation(SubmitCheck.class).checkField());
                            NotBlank blank = supField.getAnnotation(NotBlank.class);
                            throw new BusinessException(ObjectUtil.isNotEmpty(blank) ? blank.message() :
                                    superField.getAnnotation(SubmitCheck.class).checkField() + "作为判断字段,不能为空!",
                                    CommonMessageCode.FAIL.getMsgCode());
                        } else {
                            if (CollUtil.intersection(Arrays.asList(superField.getAnnotation(SubmitCheck.class).checkArray()),
                                    SubmitCheckEnum.getByCode(String.valueOf(fieldData))).size() == 0) {
                              flag = Boolean.FALSE;
                              break;
                            }
                        }
                  }
                }
                if (flag) {
                  log.info("当前字段:{},@SubmitCheck校验类型:{},@SubmitCheck校验字段:{},@SubmitCheck校验字段值:{}",
                            f.getName(), JSON.toJSONString(f.getAnnotation(SubmitCheck.class).checkArray())
                            , f.getAnnotation(SubmitCheck.class).checkField(), map.get(f.getAnnotation(SubmitCheck.class).checkField()));
                  List<SubmitCheckEnum> checkEnum = SubmitCheckEnum.getByCode(String.valueOf(map.get(f.getAnnotation(SubmitCheck.class).checkField())));
                  if (checkEnum.size() == 0) {
                        throw new BusinessException(
                              f.getName() + "字段@SubmitCheck注解配置参数checkField[" +
                                        f.getAnnotation(SubmitCheck.class).checkField() + "]," + f.getAnnotation(SubmitCheck.class).checkField() +
                                        "值无效,无法在SubmitCheckEnum映射。",
                              CommonMessageCode.FAIL.getMsgCode());
                  }
                  List<SubmitCheckEnum> submitCheckEnums = Arrays.asList(f.getAnnotation(SubmitCheck.class).checkArray());
                  if (CollUtil.intersection(submitCheckEnums, checkEnum).size() > 0) {
                        if (ObjectUtil.isEmpty(map.get(f.getName()))) {
                            NotBlank blank = f.getAnnotation(NotBlank.class);
                            throw new BusinessException(ObjectUtil.isNotEmpty(blank) ? blank.message() :
                                    f.getName() + "字段不能为空!",
                                    CommonMessageCode.FAIL.getMsgCode());
                        }
                  }
                }
            }
      });
    }

    /**
   * 判断当前字段是否有需要校验的前置条件
   */
    private static void checkSuperFieldIsEmpty(Map map,Field field,Class<?> c){
      FIELDS_NAME_LISTS.add(field.getName());
      //获取校验的前置字段
      Field superField = ReflectUtil.getField(c, field.getAnnotation(SubmitCheck.class).checkField());
      if (ObjectUtil.isNotEmpty(superField.getAnnotation(SubmitCheck.class))){
            checkSuperFieldIsEmpty(map,superField,c);
      }
    }
}







qeadzc 发表于 2023-7-28 23:32

谢谢楼主分享

苏紫方璇 发表于 2023-7-29 21:14

推荐使用这种方法插入代码
【公告】发帖代码插入以及添加链接教程(有福利)
https://www.52pojie.cn/thread-713042-1-1.html
(出处: 吾爱破解论坛)

guanhaitingfeng 发表于 2023-7-30 16:03

学习学习,谢谢楼主分享!

egol007 发表于 2023-7-30 18:12

谢谢分享

pengruibin 发表于 2023-7-31 09:13

学习了,谢谢楼主分享{:1_921:}
页: [1]
查看完整版本: 多级校验入参Vo校验注解