java 自定义注解校验实体类属性

news2024/12/26 21:00:44

直接上代码

1.是否启用参数校验注解

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EnableArgumentsCheck {

    /**
     * 是否启用
     */
    boolean enable() default true;

}

2.参数校验自定义注解

/**
 * 参数校验自定义注解
 * 属性定义:
 * name 必填,字段名称,用于参数校验失败消息提示
 * range 非必填,范围校验,Long,int,Double属性校验生效,{0,500000000}
 * decimal 非必填,Double类型校验,decimal = {5,2},校验参数为5位数保留2位小数
 * contain 非必填,参数int,String校验,{"10","20","30"}
 * isNotNull 非必填,参数是否不能为空,默认值:false,使用所有类型
 * type 非必传,,适用String类型校验,字段类型(EMAIL,MOBILE,IDENTITY_CARD,NUMBER,DATE)
 * min 非必传,Long,int,Double属性校验最小值限制,校验当前类型值不能小于min的值,默认值:Integer.MIN_VALUE
 * max 非必传,Long,int,Double属性校验最大值限制,校验当前类型值不能大于max的值,默认值:Integer.MAX_VALUE
 * pattern 非必传,参数int,String正则表达式校验
 * enumClass 非必传,枚举值校验,判断当前值是否在枚举中,enumClass和enumAttr一起使用,适用String,int
 * message 非必填,错误消息提示,默认:字段:xxx参数检验不合法
 * maxLength 非必传,最大长度限制校验,适用:Long,int,Double,string,list,arrays
 * minLength 非必传,最小长度限制校验,,适用:Long,int,Double,string,list,arrays
 * like 非必传,参数模糊匹配
 * groups 非必传,分组匹配,使用所有类型
 * formatDate 非必传,时间格式参数验证,适用string校验
 * division,非必传,校验时间是否将来时间还是过去时间,,future将来时间,past过去时间,适用date校验
 * @author 106979
 */
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PropertiesVerify {

    /**
     * 字段名称
     * @return
     */
    String name();

    /**
     * 范围range
     * @return
     */
    int[] range() default {};

    /**
     * 小数类型长度和小数位数
     * @return
     */
    int[] decimal() default {};

    /**
     * 包含字符串
     * @return
     */
    String[] contain() default {};

    /**
     * 是否为空
     */
    boolean isNotNull() default false;

    /**
     * 字段类型
     * @return
     */
    FieldType type() default FieldType.NULL;

    /**
     * Int最小值
     */
    int minInt() default Integer.MIN_VALUE;

    /**
     * Int最大值
     */
    int maxInt() default Integer.MAX_VALUE;

    /**
     * Long最小值
     */
    long minLong() default Long.MIN_VALUE;

    /**
     * Long最大值
     */
    long maxLong() default Long.MAX_VALUE;

    /**
     * 正则表达式
     */
    String pattern() default "";
    /**
     * 枚举
     * @return
     */
    Class<?> enumClass() default Void.class;
    /**
     * 分组
     * @return
     */
    Class<? extends Default>[] groups() default {};

    /**
     * 枚举方法
     * @return
     */
    String enumAttr() default "";

    /**
     * 模糊匹配
     * @return
     */
    String like() default "";

    /**
     * 时间格式
     * @return
     */
    String formatDate() default "";

    /**
     * 最大长度
     * @return
     */
    int maxLength() default -1;

    /**
     * 最小长度
     * @return
     */
    int minLength() default -1;

    /**
     * 时间分割线
     * @return
     */
    DateDivisionEnum division() default DateDivisionEnum.NONE;

    /**
     * 错误消息提示
     * @return
     */
    String message() default "%s校验不通过,%s";

    enum FieldType {
        NULL("", ""),
        EMAIL("邮箱", "^[A-Za-z\\d]+([-_.][A-Za-z\\d]+)*@([A-Za-z\\d]+[-.])+[A-Za-z\\d]{2,4}$"),
        MOBILE("手机号码", "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(16[5,6])|(17[0-8])|(18[0-9])|(19[1、5、8、9]))\\\\d{8}$"),
        IDENTITY_CARD("身份证", "^[1-9]\\\\d{5}[1-9]\\\\d{3}((0\\\\d)|(1[0-2]))(([0|1|2]\\\\d)|3[0-1])\\\\d{3}([\\\\d|x|X]{1})$"),
        NUMBER("正整数", "^[0-9]*[1-9][0-9]*$"),
        DATE("日期", "((^((1[8-9]\\d{2})|([2-9]\\d{3}))([-\\/\\._])(10|12|0?[13578])([-\\/\\._])(3[01]|[12][0-9]|0?[1-9])$)|(^((1[8-9]\\d{2})|([2-9]\\d{3}))([-\\/\\._])(11|0?[469])([-\\/\\._])(30|[12][0-9]|0?[1-9])$)|(^((1[8-9]\\d{2})|([2-9]\\d{3}))([-\\/\\._])(0?2)([-\\/\\._])(2[0-8]|1[0-9]|0?[1-9])$)|(^([2468][048]00)([-\\/\\._])(0?2)([-\\/\\._])(29)$)|(^([3579][26]00)([-\\/\\._])(0?2)([-\\/\\._])(29)$)|(^([1][89][0][48])([-\\/\\._])(0?2)([-\\/\\._])(29)$)|(^([2-9][0-9][0][48])([-\\/\\._])(0?2)([-\\/\\._])(29)$)|(^([1][89][2468][048])([-\\/\\._])(0?2)([-\\/\\._])(29)$)|(^([2-9][0-9][2468][048])([-\\/\\._])(0?2)([-\\/\\._])(29)$)|(^([1][89][13579][26])([-\\/\\._])(0?2)([-\\/\\._])(29)$)|(^([2-9][0-9][13579][26])([-\\/\\._])(0?2)([-\\/\\._])(29)$))");

        public String name;

        public String regular;

        FieldType(String name, String regular) {
            this.name = name;
            this.regular = regular;
        }
    }

}

3.参数校验接口

/**
 * 参数校验接口
 * @author zcs
 */
public interface ArgumentsVerify {
    /**
     * 默认参数校验
     * @return
     */
    String check();
}

4.参数校验抽象类,提供基础校验方法,以及继承抽象类的子类.

public abstract class AbstractArgumentsVerify implements ArgumentsVerify {

    private static final String DECIMAL_POINT = "\\.";

    private static final int ARRAY_LENGTH = 2;

    protected Object inputData;

    protected PropertiesVerify propertiesVerify;

    protected Class<? extends Default> groups;

    AbstractArgumentsVerify(Object inputData, PropertiesVerify propertiesVerify, Class<? extends Default> groups) {
        this.inputData = inputData;
        this.propertiesVerify = propertiesVerify;
        this.groups = groups;
    }


    /**
     * 包含校验
     * @return
     */
    public String isContain() {
        if (inputData != null
                && propertiesVerify != null
                && propertiesVerify.contain() != null
                && propertiesVerify.contain().length > 0
                && !Arrays.asList(propertiesVerify.contain()).contains(inputData.toString())) {
            return getMsg("不存在指定值范围内");
        }
        return StringUtils.EMPTY;
    }


    /**
     * 时间类型校验
     * @return
     */
    public String isFormatDate() {
        if (inputData == null) {
            return StringUtils.EMPTY;
        }

        if (StringUtils.isNotBlank(propertiesVerify.formatDate())) {

            Date d = null;
            try {
                SimpleDateFormat sdf = new SimpleDateFormat(propertiesVerify.formatDate(), Locale.CHINA);
                d = sdf.parse(inputData.toString());
            } catch (ParseException e) {
              throw new RuntimeException("参数校验时间格式错误");
            }
            if (d == null) {
                return getMsg("时间格式错误");
            }
        }
        return StringUtils.EMPTY;
    }

    /**
     * 时间分界校验
     * @return
     */
    public String division() {
        if (inputData == null) {
            return StringUtils.EMPTY;
        }
        if (propertiesVerify.division() != null && !DateDivisionEnum.NONE.equals(propertiesVerify.division())) {

            Date d = (Date) inputData;
            Date currentDate = new Date();
            switch (propertiesVerify.division()) {
                case FUTURE:
                    if (!d.after(currentDate)) {
                        return getMsg("必须大于当前时间");
                    }
                    break;
                case PAST:
                    if (!d.before(currentDate)) {
                        return getMsg("必须小于当前时间");
                    }
                    break;
            }
        }
        return StringUtils.EMPTY;
    }

    /**
     * 最小值参数校验
     * @return
     */
    public String isMinInt() {
        if (inputData == null) {
            return StringUtils.EMPTY;
        }
        int intVal = 0;
        try {
            intVal = (int) inputData;
        } catch (Exception e) {
            //非数字类型不校验
        }
        if (propertiesVerify.minInt() > intVal) {
            return getMsg("输入值小于指定最小值");
        }
        return StringUtils.EMPTY;
    }

    /**
     * 最大值
     * @return
     */
    public String isMaxInt() {
        if (inputData == null) {
            return StringUtils.EMPTY;
        }
        int intVal = 0;
        try {
            intVal = (int) inputData;
        } catch (Exception e) {
            //非数字类型不校验
        }
        if (propertiesVerify.maxInt() < intVal) {
            return getMsg("输入值大于指定最大值");
        }
        return StringUtils.EMPTY;
    }


    /**
     * 最小值参数校验
     * @return
     */
    public String isMinLong() {
        if (inputData == null) {
            return StringUtils.EMPTY;
        }
        long longVal = 0;
        try {
            longVal = (long) inputData;
        } catch (Exception e) {
            //非数字类型不校验
        }
        if (propertiesVerify.minLong() > longVal) {
            return getMsg("输入值小于指定最小值");
        }
        return StringUtils.EMPTY;
    }

    /**
     * 最大值
     * @return
     */
    public String isMaxLong() {
        if (inputData == null) {
            return StringUtils.EMPTY;
        }
        long longVal = 0;
        try {
            longVal = (long) inputData;
        } catch (Exception e) {
            //非数字类型不校验
        }
        if (propertiesVerify.maxLong() < longVal) {
            return getMsg("输入值大于指定最大值");
        }
        return StringUtils.EMPTY;
    }

    /**
     * 最小长度
     * @return
     */
    public String minLength() {
        if (inputData == null) {
            return StringUtils.EMPTY;
        }
        if (propertiesVerify.minLength() > 0) {
            int length;
            length = getLength();
            if (length < propertiesVerify.minLength()) {
                return getMsg("输入值长度小于最小值");
            }
        }
        return StringUtils.EMPTY;
    }

    /**
     * 最大长度
     * @return
     */
    public String maxLength() {
        if (inputData == null) {
            return StringUtils.EMPTY;
        }
        if (propertiesVerify.maxLength() > 0) {
            int length;
            length = getLength();
            if (length > propertiesVerify.maxLength()) {
                return getMsg("输入值长度大于最大值");
            }
        }
        return StringUtils.EMPTY;
    }


    private int getLength() {
        int length;
        if (inputData instanceof Map) {
            Map mapData = (Map) inputData;
            length = mapData.size();
        } else if (inputData instanceof List) {
            List listData = (List) inputData;
            length = listData.size();
        } else if (inputData instanceof Collection) {
            Collection collectionData = (Collection) inputData;
            length = collectionData.size();
        } else if (inputData.getClass().isArray()) {
            length = Arrays.asList(inputData).size();
        } else {
            length = inputData.toString().length();
        }
        return length;
    }


    /**
     * 取值范围
     * @return
     */
    public String range() {
        if (inputData == null) {
            return StringUtils.EMPTY;
        }
        BigDecimal b = null;
        try {
            b = new BigDecimal(inputData.toString());
        } catch (Exception e) {
            //非数字类型不校验
        }
        if (b != null
                && propertiesVerify.range() != null
                && propertiesVerify.range().length >= ARRAY_LENGTH
                && (b.doubleValue() > propertiesVerify.range()[1] || b.doubleValue() < propertiesVerify.range()[0])) {
            return getMsg(String.format("输入值必须在%s-%s范围内", propertiesVerify.range()[0], propertiesVerify.range()[1]));
        }
        return StringUtils.EMPTY;
    }

    /**
     * 模糊匹配
     * @return
     */
    public String isLike() {
        if (inputData == null) {
            return StringUtils.EMPTY;
        }
        if (StringUtils.isNotBlank(propertiesVerify.like())
                && !inputData.toString().contains(propertiesVerify.like())) {
            return getMsg(String.format("参数必须包含[%s]", propertiesVerify.like()));
        }
        return StringUtils.EMPTY;
    }

    /**
     * 字段类型枚举
     * @return
     */
    public String type() {
        if (inputData == null) {
            return StringUtils.EMPTY;
        }
        if (propertiesVerify.type() != null && StringUtils.isNotBlank(propertiesVerify.type().regular)) {
            Pattern pat = Pattern.compile(propertiesVerify.type().regular);
            Matcher mat = pat.matcher(inputData.toString());
            boolean isMatch = mat.matches();
            if (!isMatch) {
                return getMsg(String.format("参数不匹配类型:", propertiesVerify.type().name));
            }
        }
        return StringUtils.EMPTY;
    }

    /**
     * 小数范围
     * @return
     */
    public String decimal() {
        if (inputData == null) {
            return StringUtils.EMPTY;
        }
        if (propertiesVerify.decimal() != null && propertiesVerify.decimal().length >= ARRAY_LENGTH) {
            //全部位数
            int digitsNumber = propertiesVerify.decimal()[0];
            //小数位数
            int decimalNumber = propertiesVerify.decimal()[1];
            String strVal = inputData.toString().replace("-", "");
            if (StringUtils.contains(strVal, ".")) {
                int intLength = strVal.split(DECIMAL_POINT)[0].length();
                int decimalLength = strVal.split(DECIMAL_POINT)[1].length();
                if (intLength + decimalLength > digitsNumber) {
                    return getMsg(String.format("参数不能超过%s位", digitsNumber));
                }
                if (decimalLength > decimalNumber) {
                    return getMsg(String.format("小数不能超过%s位", decimalNumber));
                }
            } else {
                int intLength = strVal.length();
                if (intLength > digitsNumber) {
                    return getMsg(String.format("参数不能超过%s位", digitsNumber));
                }
            }
        }
        return StringUtils.EMPTY;
    }

    /**
     * 自定义正则表达式
     * @return
     */
    public String pattern() {
        if (inputData == null) {
            return StringUtils.EMPTY;
        }
        if (StringUtils.isNotBlank(propertiesVerify.pattern())) {
            Pattern pat = Pattern.compile(propertiesVerify.pattern());
            Matcher mat = pat.matcher(inputData.toString());
            boolean isMatch = mat.matches();
            if (!isMatch) {
                return getMsg("参数不满足正则表达式");
            }
        }
        return StringUtils.EMPTY;
    }

    /**
     * 枚举值
     * @return
     */
    public String enumVal() {
        if (inputData == null) {
            return StringUtils.EMPTY;
        }
        if (propertiesVerify.enumClass() != null
                && propertiesVerify.enumClass() != Void.class
                && StringUtils.isNotBlank(propertiesVerify.enumAttr())) {
            try {
                // 2.得到所有枚举常量
                Object[] objects = propertiesVerify.enumClass().getEnumConstants();
                String methodName = "get" + propertiesVerify.enumAttr().substring(0, 1).toUpperCase() + propertiesVerify.enumAttr().substring(1);
                Method method = propertiesVerify.enumClass().getMethod(methodName);
                boolean isInclude = false;
                for (Object obj : objects) {
                    // 3.调用对应方法,得到枚举常量中字段的值
                    Object val = method.invoke(obj);
                    if (val != null && inputData.toString().equals(val + "")) {
                        isInclude = true;
                        break;
                    }
                }
                if (!isInclude) {
                    return getMsg("参数不在指定枚举值中");
                }
            } catch (Exception e) {
                //todo 异常处理
                System.out.println(e.getMessage());
            }
        }
        return StringUtils.EMPTY;
    }

    private String getMsg(String desc) {
        return String.format(propertiesVerify.message(), propertiesVerify.name(), desc);
    }
}

实现类型 :
 

public class DateArgumentsVerify extends AbstractArgumentsVerify {

    public DateArgumentsVerify(Date val, PropertiesVerify propertiesVerify, Class<? extends Default> groups) {
        super(val, propertiesVerify, groups);
    }

    @Override
    public String check() {
        String res = super.division();
        if (StringUtils.isNotBlank(res)) {
            return res;
        }
        return StringUtils.EMPTY;
    }
}
public class DoubleArgumentsVerify extends AbstractArgumentsVerify {

    public DoubleArgumentsVerify(String val, PropertiesVerify propertiesVerify, Class<? extends Default> groups) {
        super(val, propertiesVerify, groups);
    }

    @Override
    public String check() {
        //包含校验
        String res = super.maxLength();
        if (StringUtils.isNotBlank(res)) {
            return res;
        }
        res = super.minLength();
        if (StringUtils.isNotBlank(res)) {
            return res;
        }
        res = super.decimal();
        if (StringUtils.isNotBlank(res)) {
            return res;
        }
        res = super.isLike();
        if (StringUtils.isNotBlank(res)) {
            return res;
        }
        res = super.range();
        return res;
    }
}
public class IntegerArgumentsVerify extends AbstractArgumentsVerify {

    public IntegerArgumentsVerify(Integer val, PropertiesVerify propertiesVerify, Class<? extends Default> groups) {
        super(val, propertiesVerify, groups);
    }

    @Override
    public String check() {
        //包含校验
        String res = super.isContain();
        if (StringUtils.isNotBlank(res)) {
            return res;
        }
        res = super.maxLength();
        if (StringUtils.isNotBlank(res)) {
            return res;
        }
        res = super.minLength();
        if (StringUtils.isNotBlank(res)) {
            return res;
        }
        //最小值校验
        res = super.isMinInt();
        if (StringUtils.isNotBlank(res)) {
            return res;
        }
        res = super.pattern();
        if (StringUtils.isNotBlank(res)) {
            return res;
        }
        res = super.isLike();
        if (StringUtils.isNotBlank(res)) {
            return res;
        }
        res = super.enumVal();
        if (StringUtils.isNotBlank(res)) {
            return res;
        }
        //最大值校验
        res = super.isMaxInt();
        if (StringUtils.isNotBlank(res)) {
            return res;
        }
        res = super.range();
        return res;
    }
}
public class ListArgumentsVerify extends AbstractArgumentsVerify {

    public ListArgumentsVerify(List<Object> val, PropertiesVerify propertiesVerify, Class<? extends Default> groups) {
        super(val, propertiesVerify, groups);
    }

    @Override
    public String check() {
        //校验List类型参数
        String res = super.minLength();
        if (StringUtils.isNotBlank(res)) {
            return res;
        }
        res = super.maxLength();
        if (StringUtils.isNotBlank(res)) {
            return res;
        }

        if (CollectionUtils.isNotEmpty((Collection) super.inputData)) {
            for (Object obj : (Collection) super.inputData) {
                res = ArgumentsCheckUtil.check(obj, super.groups);
                if (StringUtils.isNotBlank(res)) {
                    break;
                }
            }
        }
        return res;
    }
}
public class LongArgumentsVerify extends AbstractArgumentsVerify {

    public LongArgumentsVerify(Long val, PropertiesVerify propertiesVerify, Class<? extends Default> groups) {
        super(val, propertiesVerify, groups);
    }

    @Override
    public String check() {
        String res = super.maxLength();
        if (StringUtils.isNotBlank(res)) {
            return res;
        }
        res = super.minLength();
        if (StringUtils.isNotBlank(res)) {
            return res;
        }
        res = super.isLike();
        if (StringUtils.isNotBlank(res)) {
            return res;
        }
        //最小值校验
        res = super.isMinLong();
        if (StringUtils.isNotBlank(res)) {
            return res;
        }
        //最大值校验
        res = super.isMaxLong();
        if (StringUtils.isNotBlank(res)) {
            return res;
        }
        res = super.range();
        return res;
    }
}
public class StringArgumentsVerify extends AbstractArgumentsVerify {

    public StringArgumentsVerify(String val, PropertiesVerify propertiesVerify, Class<? extends Default> groups) {
        super(val, propertiesVerify, groups);
    }

    @Override
    public String check() {
        //包含校验
        if(StringUtils.isBlank((String)inputData)){
            return "";
        }
        String res = super.isContain();
        if (StringUtils.isNotBlank(res)) {
            return res;
        }
        res = super.isLike();
        if (StringUtils.isNotBlank(res)) {
            return res;
        }
        res = super.type();
        if (StringUtils.isNotBlank(res)) {
            return res;
        }
        res = super.pattern();
        if (StringUtils.isNotBlank(res)) {
            return res;
        }
        res = super.enumVal();
        if (StringUtils.isNotBlank(res)) {
            return res;
        }
        res = super.maxLength();
        if (StringUtils.isNotBlank(res)) {
            return res;
        }
        res = super.isFormatDate();
        if (StringUtils.isNotBlank(res)) {
            return res;
        }
        res = super.minLength();
        return res;
    }
}

5.使用到的枚举

/**
 * 时间检验分割线
 * @author 106979
 */
public enum DateDivisionEnum {

    NONE("无"),

    FUTURE("将来时间"),

    PAST("过去时间");

    public String name;

    DateDivisionEnum(String name) {
        this.name = name;
    }
}

6.工具类:

public class ArgumentsCheckUtil {

    /**
     * 参数验证
     * @param cla 需要校验的对象
     * @return 校验异常消息
     */
    public static String check(Object cla) {
        return check(cla, null);
    }

    /**
     * 参数验证
     * @param cla 需要校验的对象
     * @param groups 分组
     * @return 校验异常消息
     */
    public static String check(Object cla, Class<? extends Default> groups) {
        if (cla != null) {
            EnableArgumentsCheck enableArgumentsCheck = cla.getClass().getAnnotation(EnableArgumentsCheck.class);
            if (enableArgumentsCheck == null || !enableArgumentsCheck.enable()) {
                return StringUtils.EMPTY;
            }
            Field[] fields = cla.getClass().getDeclaredFields();
            for (Field f : fields) {
                PropertiesVerify propertiesVerify = f.getAnnotation(PropertiesVerify.class);
                if (propertiesVerify == null) {
                    continue;
                }
                f.setAccessible(true);
                Object value = null;
                try {
                    value = getFieldValue(f.getName(), cla);
                } catch (Exception e) {
                    throw new RuntimeException(String.format("获取字段:%s值异常", f.getName()));
                }

                //分组判断
                if (isMatchGroups(groups, propertiesVerify)) {
                    continue;
                }
                //判断是否为空
                if (value == null && propertiesVerify.isNotNull()) {
                    return String.format("参数:%s不能为空", propertiesVerify.name());
                }
                if(Objects.isNull(value)){
                    continue;
                }
                String res;
                if (value instanceof String) {
                    //校验字符串参数
                    res = new StringArgumentsVerify((String) value, propertiesVerify, groups).check();
                } else if (value instanceof Long) {
                    //检验Long类型参数
                    res = new LongArgumentsVerify(Long.parseLong(value.toString()), propertiesVerify, groups).check();
                } else if (value instanceof Integer) {
                    //校验Integer类型参数
                    res = new IntegerArgumentsVerify(Integer.parseInt(value.toString()), propertiesVerify, groups).check();
                } else if (value instanceof Double) {
                    //校验Double类型参数
                    res = new DoubleArgumentsVerify(formatDouble((Double) value), propertiesVerify, groups).check();
                } else if (value instanceof Date) {
                    //校验Date类型参数
                    res = new DateArgumentsVerify((Date) value, propertiesVerify, groups).check();
                } else if (value instanceof List) {
                    //list判断
                    res = new ListArgumentsVerify((List<Object>) value, propertiesVerify, groups).check();
                } else if (value.getClass().isArray()) {
                    //校验数组类型参数
                    res = new ListArgumentsVerify(Arrays.asList((Object[]) value), propertiesVerify, groups).check();
                } else {
                    return check(value);
                }
                if (StringUtils.isNotBlank(res)) {
                    return res;
                }
            }
        }
        return StringUtils.EMPTY;
    }


    private static String formatDouble(Double d) {
        NumberFormat nf = NumberFormat.getInstance();
        //设置保留多少位小数
        nf.setMaximumFractionDigits(20);
        // 取消科学计数法
        nf.setGroupingUsed(false);
        //返回结果
        return nf.format(d);
    }

    private static boolean isMatchGroups(Class<? extends Default> groups, PropertiesVerify propertiesVerify) {
        if (groups != null) {
            Class<? extends Default>[] fieldGroups = propertiesVerify.groups();
            if (fieldGroups != null) {
                boolean isMatchGroup = false;
                for (Class c : fieldGroups) {
                    if (c == groups) {
                        isMatchGroup = true;
                        break;
                    }
                }
                if(!isMatchGroup){
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * @param fieldName 属性名称
     * @param o         属性对象
     * @return Object
     * @throws IllegalAccessException
     * @throws IllegalArgumentException
     * @throws InvocationTargetException
     * @throws NoSuchMethodException
     * @throws SecurityException
     * @Title: getFieldValue
     * @Description: 获取对象属性的值
     * @author ZENGCHONG
     */
    public static Object getFieldValue(String fieldName, Object o) throws Exception {
        String firstLetter = fieldName.substring(0, 1).toUpperCase();
        String getter = "get" + firstLetter + fieldName.substring(1);
        Method method = o.getClass().getMethod(getter);
        Object value = method.invoke(o);
        return value;
    }
}

7.实体类(用于测试)

@Data
@EnableArgumentsCheck()
public class PrepareOrderRouteReq {

    /**
     * 
     */
    @PropertiesVerify(name = "下单编码", isNotNull = true, minLength = 1, maxLength = 200)
    private String orderNumber;

    private String plateNumber;

}

8.测试类

public class processTest {

    public static void main(String[] args) {
        PrepareOrderRouteReq req = new PrepareOrderRouteReq();
        req.setOrderNumber("{\n" +
                "\t\"actualWeight\": 88.0,\n" +
                "\t\"addWorkday\": 1.0,\n" +
                "\t\"autoDistributionFlag\": 10,\n" +
                "\t\"billFlag\": \"20\",\n" +
                "\t\"contraband\": 20,\n" +
                "\t\"createTime\": 1725865110020,\n" +
                "\t\"customerServiceId\": \"12163\",\n" +
                "\t\"customerServiceName\": \"客服中台中心\",\n" +
                "\t\"deliveryAddWorkday\": 0.0,\n" +
                "\t\"deliveryAging\": 1726037880000,\n" +
                "\t\"freightAmount\": 0.0,\n" +
                "\t\"goodsCategory\": \"\",\n" +
                "\t\"goodsLabel\": \"40\",\n" +
                "\t\"goodsSize\": \"\",\n" +
                "\t\"goodsType\": \"托寄物青0瓜\",\n" +
                "\t\"id\": \"155872956798825217\",\n" +
                "\t\"invalidFlag\": 20,\n" +
                "\t\"linePlusAddDay\": 0.0,\n" +
                "\t\"newCustomerFlag\": 20,\n" +
                "\t\"nightOvertime\": \"10\",\n" +
                "\t\"orderTime\": 1725865100000,\n" +
                "\t\"orderUploadMode\": \"20\",\n" +
                "\t\"pickupAddWorkday\": 1.0,\n" +
                "\t\"pickupTime\": \"2024-09-09 14:58:00\",\n" +
                "\t\"predictWeight\": 50.0,\n" +
                "\t\"receiveAddress\": \"上海市闵行区江川路690号上海电机学院(闵行校区)\",\n" +
                "\t\"receiveAreaCode\": \"10\",\n" +
                "\t\"receiveCustomerCode\": \"02106680981\",\n" +
                "\t\"receiveCustomerId\": \"8898771\",\n" +
                "\t\"receiveCustomerName\": \"上海每林\",\n" +
                "\t\"receiveMobile\": \"B2F64BDFB2A77B477C35867C00B7FDC5\",\n" +
                "\t\"receiveNodeId\": \"3997\",\n" +
                "\t\"receiveNodeName\": \"闵行点部\",\n" +
                "\t\"receivePhone\": \"0A967228DE1933E879C7F46FF845C8E8\",\n" +
                "\t\"receiveRegionCode\": \"021\",\n" +
                "\t\"reportNodeId\": \"5141\",\n" +
                "\t\"reportNodeName\": \"松岗新桥点部\",\n" +
                "\t\"requestFromAirport\": \"温州\",\n" +
                "\t\"requestToAirport\": \"上海虹桥\",\n" +
                "\t\"safetyCheck\": \"20\",\n" +
                "\t\"saleProjectCode\": \"XM-202204-0049\",\n" +
                "\t\"sendAddress\": \"广东省深圳市宝安区松岗街道松岗中心幼儿园2号1\",\n" +
                "\t\"sendAreaCode\": \"20\",\n" +
                "\t\"sendCustomerCode\": \"075508105755\",\n" +
                "\t\"sendCustomerId\": \"2207729\",\n" +
                "\t\"sendCustomerName\": \"深圳三四川科技\",\n" +
                "\t\"sendMobile\": \"C19C06D177CF75380C3754D5FABC24E8\",\n" +
                "\t\"sendNodeId\": \"5141\",\n" +
                "\t\"sendNodeName\": \"松岗新桥点部\",\n" +
                "\t\"sendRegionCode\": \"0755\",\n" +
                "\t\"serviceMode\": \"20\",\n" +
                "\t\"specialCode\": \"\",\n" +
                "\t\"transferFlag\": \"20\",\n" +
                "\t\"updateTime\": 1725865112166,\n" +
                "\t\"volumeWeight\": 0.0,\n" +
                "\t\"waybillCount\": 10,\n" +
                "\t\"waybillNo\": \"KY5000249115370\",\n" +
                "\t\"waybillRemark\": \"运单备注米123兰含电池\",\n" +
                "\t\"waybillSource\": \"240\",\n" +
                "\t\"waybillStatus\": \"70\",\n" +
                "\t\"waybillType\": \"2010\",\n" +
                "\t\"woodenFrameFlag\": \"\"\n" +
                "}");
        String check = ArgumentsCheckUtil.check(req);
        System.out.println(check);
    }
}

结果:

使用到的jar包

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.18</version>
        </dependency>

         <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>2.0.1.Final</version>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.12.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-collections4</artifactId>
            <version>4.4</version>
        </dependency>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2119074.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

打造企业专属品牌,就要跟上云微客短视频矩阵新风口

网红经济在经济发展中是一个周期性的事件&#xff0c;很多人还没有意识到短视频带货、直播带货等红利时&#xff0c;有一群人早就已经进去了。但是现在网红带货时代已经结束了&#xff0c;那么新的风口是什么呢&#xff1f; 其实找网红带货&#xff0c;看似是提高了销售业绩&am…

[CTF夺旗赛] CTFshow Web1-12 详细过程保姆级教程~

文章目录 前言Web1Web2Web3Web4Web5Web6Web7Web8Web9Web10Web11Web12 前言 ​ CTFShow通常是指网络安全领域中的“Capture The Flag”(夺旗赛)展示工具或平台。这是一种用于分享、学习和展示信息安全竞赛中获取的信息、漏洞利用技巧以及解题思路的在线社区或软件。参与者会在比…

Linux IO模型(多路复用)

【1】Linux IO模型&#xff1a;IO多路复用 场景假设二 假设妈妈有三个孩子&#xff0c;分别不同的房间里睡觉&#xff0c;需要及时获知每个孩子是否醒了&#xff0c;如何做&#xff1f; 1.一直在一个房间呆着&#xff1a;看不到其他两个孩子 2.每个房间不停的看&#xff1a;可以…

python进阶篇-day09-数据结构与算法(非线性结构与排序算法)

非线性结构(树状结构) 特点: 每个节点都可以有n个子节点(后继节点) 和 n个父节点(前驱节点) 代表: 树, 图...... 概述 属于数据结构之 非线性结构的一种, 父节点可以有多个子节点(后续节点) 特点 有且只有1个根节点 每个节点都可以有1个父节点及任意个子节点, 前提: 根节点除…

C 408—《数据结构》算法题基础篇—链表(上)

目录 Δ前言 一、链表中特定值结点的删除 0.题目&#xff1a; 1.算法设计思想&#xff1a; 2.C语言描述&#xff1a; 3.算法的时间和空间复杂度&#xff1a; 二、链表链表最小值结点的删除 0.题目 : 1.算法设计思想 : 2.C语言描述 : 3.算法的时间和空间复杂度 : 三、链…

E32.【C语言】练习:指针运算习题集(下)(未完)

Exercise 6:阿里巴巴面试题 求下列代码的执行结果 #include <stdio.h> int main() {char *a[] {"work","at","alibaba"};char**pa a;pa;printf("%s\n", *pa);return 0; } 答案速查: 分析: char *a[] {"work",…

计算机组成原理(第一课)

计算机系统概述 1.发展史 摩尔定律&#xff1a;集成电路上可以容纳的晶体管数目在大约每经过18个月到24个月便会增加一倍 2.操作系统组成 存储程序程序控制 五个部分记住&#xff1a; 输入输出功能 I/O 记忆功能 访问 计算功能 计算 判断功能 判断 自我控制功能 自我控制…

冲呀!6款最佳企业文件加密软件排名

在当前数字化时代&#xff0c;企业数据的安全性和保密性已成为企业运营中不可忽视的重要环节。文件加密软件作为保护企业敏感数据的有效工具&#xff0c;其重要性日益凸显。以下是六款最佳企业文件加密软件的排名及详细介绍&#xff0c;这些软件均以其卓越的性能、安全性和易用…

Parsec被墙/800报错/无法访问/连接错误/被封解决方案

Parsec被墙老问题了&#xff0c;给小白们推荐一些解决方式&#xff1a; 800报错的话&#xff1a;把猫的tun模式打开&#xff0c;然后安装服务模式&#xff0c;再登录就可以了&#xff1b; 6023&#xff1a;开IPV6就能解决。 因为Parsec被墙不是一次两次了&#xff0c;我建议…

“简易不简单,全志H616开发环境配置,让创意快速转化为现实!“#全志H616开发板开发环境简易配置

"简易不简单&#xff0c;全志H616开发环境配置&#xff0c;让创意快速转化为现实&#xff01;"#全志H616开发板简易配置开发环境 前言预备知识一、 全志H616学习方向1.1 为什么学1.2 学什么 二、 H616开发板OrangePiZero2 介绍2.1 平台介绍2.2 平台特性2.3 配套操作系…

关于武汉芯景科技有限公司的IIC电平转换芯片XJ4300开发指南(兼容LTC4300)

一、芯片引脚介绍 1.芯片引脚 2.引脚描述 二、系统结构图 三、功能描述 1.电平转换

算法工程师重生之第二天(长度最小的子数组 螺旋矩阵II 区间和 开发商购买土地 总结 )

参考文献 代码随想录 一、长度最小的子数组 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl, numsl1, ..., numsr-1, numsr] &#xff0c;并返回其长度。如果不存在符合条件的子数组&#xff0c…

单细胞拟时序/轨迹分析原理及monocle2流程学习和整理

在生命演进的过程中机体会随着时间的变化而产生不同的变化。从婴幼儿长大为成年人再到老年人的过程中&#xff0c;我们的身体机能经历了从"弱-强-弱"的变化过程(宽泛的说)&#xff0c;以年为单位来看&#xff0c;有可能我们在10多岁的时候一年内一下子长高了几十厘米…

ArcGIS中怎么合并多个点图层并删除重复点?

最近&#xff0c;我接到了一个怎么合并多个点图层并删除其中的重复点的咨询。 下面是我对这个问题的解决思路&#xff1a; 1、合并图层 在地理处理工具里面 选择合并 并设置好要合并的图层即可 2、接下来在 数据管理工具→常规→删除相同项 即可 希望这些建议能对大家有所帮…

blender云渲染来了,blender云渲染教程!

朋友们&#xff0c;成都渲染101农场blender云渲染上线了&#xff0c;继3DMAX/C4D/maya/UE5云渲染上线后&#xff0c;又上线了blender云渲染&#xff0c;今天&#xff0c;成都渲染101渲染农场用四步教会您blender云渲染&#xff01; 第一步&#xff0c;云渲码6666注册个渲染101…

关于elasticsearch的terms查询超过最大terms数

当我使用es的terms查询时&#xff0c;报错了这段内容。 failed to create query: The number of terms [80306] used in the Terms Query request has exceeded the allowed maximum of [65536]. This maximum can be set by changing the [index.max_terms_count] index leve…

Web日志分析工具GoAccess

目录 1. 介绍 2. 功能 3. 支持的格式 4. 安装 从发布版本构建 从GitHub构建&#xff08;开发&#xff09; 命令行安装 5. 使用 5.1 监视Apache日志 5.2 通过web仪表板查看日志 浏览器访问 5.3 汉化设置 测试访问 1. 介绍 GoAccess是一个开源的实时网络日志分析器和…

VS Code 文件定位功能

1、取消“当前打开文件”的自动定位功能。 设置 ->搜索 Explorer: Auto Reveal -> 将配置改为 false 2.在vs2017中定位文件 Tools->Option->Projects And Solutions->General, tick “track Active Item in Solution Explorer” 工具-> 选项->项目和…

网络基础入门指南(一)

前言 在这个高度互联的世界里&#xff0c;互联网已成为日常生活不可或缺的一部分。然而&#xff0c;对于许多人来说&#xff0c;网络是如何工作的仍然是个谜。本文旨在为那些对网络基础知识感兴趣的朋友提供一个简单的介绍&#xff0c;帮助大家更好地理解互联网的基本原理和技…

输出CAD图中第一个图元类型——c#实现

复制改图元到一个新dwg中&#xff0c;启动代码可实现 如下图设置&#xff1a; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.Runtime; using System; using System.Collections.Generic; using System.Linq…