吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 855|回复: 5
收起左侧

[Java 原创] 多级校验入参Vo校验注解

[复制链接]
15212562657 发表于 2023-7-27 17:24
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);
        }
    }
}







Vo字段注解 可以搭配@NotBlank使用

Vo字段注解 可以搭配@NotBlank使用

免费评分

参与人数 1吾爱币 +7 热心值 +1 收起 理由
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

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
学习了,谢谢楼主分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 21:01

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表