• 通过自定义注解校验后台接口请求参数


    定义一个自定义注解类

    /**
     * @Author 田海超
     * @Date 2019/12/10 10:04
     * @Description TODO 非空注解
     **/
    @Target({ElementType.FIELD, ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface ParamNotNull {
        // 指定值
        String value() default "";
    
        // 中文描述
        String describeName() default "";
    
        //BigDecimal类型保留位数
        int bigDecimalDigit() default -1;
    }

    在接口对象中使用注解(如若使用代码,请自行补全set和get方法)

    /**
     * @Author 田海超
     * @Date 2019/12/6 15:52
     * @Description TODO 提结接口请求参数VO
     **/
    public class RequestObjectDemoVO{
        @ParamNotNull(describeName = "请求/响应序列号")
        private String seqReqNo;//请求/响应序列号
        @ParamNotNull(describeName = "接口类型", value = "prepayment_cf")
        private String interfaceType;//接口类型
        @ParamNotNull(describeName = "接口版本", value = "version1.0.0")
        private String versionNo;//接口版本
        @ParamNotNull(describeName = "进件流水号")
        private String businessNo;//进件流水号
        @ParamNotNull(describeName = "总金额", bigDecimalDigit = 2)
        private String paymentSum;//总金额
        @ParamNotNull(describeName = "本金", bigDecimalDigit = 2)
        private String balance;//本金
        @ParamNotNull(describeName = "利息", bigDecimalDigit = 2)
        private String inte;//利息
        @ParamNotNull(describeName = "保费", bigDecimalDigit = 2)
        private String premium;//保费
        @ParamNotNull(describeName = "服务费", bigDecimalDigit = 2)
        private String commission;//服务费
        @ParamNotNull(describeName = "还款来源", value = "01")
        private String paymentSource;//还款来源   01 客户还款
    }

    通过反射使用自定义注解校验对象属性值

    /**
     * @Author 田海超
     * @Date 2019/12/10 10:36
     * @Description TODO 校验工具类
     **/
    public class VerifyUtils {
        /**
         * @return java.lang.String
         * @Author 田海超
         * @Description //TODO 根据非空校验注解校验对象属性是否为空和字段值是否正确
         * @Date 10:35 2019/12/10
         * @Param [object, errorMessage[] 异常描述:errorMessage[0] -->不为空的异常描述;errorMessage[1] -->值校验错误的异常描述;errorMessage[2] -->数字数位校验错误的异常描述]
         **/
        public static String VerifyNotNullAndValueIsRight(Object object, String... errorMessage) {
            if (object == null) {
                throw new IllegalArgumentException();
            }
            try {
                // 反射获得对象类属性列表
                Field[] fields = object.getClass().getDeclaredFields();
                for (Field field : fields) {
                    if (field.isAnnotationPresent(ParamNotNull.class)) {
                        // 该处使可以获得私有属性值
                        field.setAccessible(true);
                        Object value = field.get(object);
                        String annotationValue = field.getAnnotation(ParamNotNull.class).describeName();
                        if (value == null) {
                            return MessageFormat.format(errorMessage[0], annotationValue);
                        }
                        //字符串校验空字符
                        if (value instanceof String && StringUtils.isBlank((String) value)) {
                            return MessageFormat.format(errorMessage[0], annotationValue);
                        }
                        String idealValue = field.getAnnotation(ParamNotNull.class).value();
                        // 如果配置了指定值,校验传入值是否符合要求
                        if (StringUtils.isNotBlank(idealValue)) {
                            if (!idealValue.equals(value)) {
                                return MessageFormat.format(errorMessage[1], annotationValue);
                            }
                            if (value instanceof String && !StringUtils.equals((String) value, idealValue)) {
                                return MessageFormat.format(errorMessage[1], annotationValue);
                            }
                        }
                        // 配置了bigDecimalDigit数目这个字段期望被转化成digit位的数字,这里添加校验
                        int digit = field.getAnnotation(ParamNotNull.class).bigDecimalDigit();
                        if (digit != -1 && value instanceof String && errorMessage.length >= 3 && !AbsUtil.checkDoubleNumber((String) value, digit, true)) {// 校验位数
                            return MessageFormat.format(errorMessage[2], annotationValue);
                        }
                    }
                }
            } catch (IllegalAccessException e) {
                throw new IllegalArgumentException("参数非空校验获取参数值时异常");
            }
            return "";
        }
    
        public static void main(String[] args) {
            System.out.println(new BigDecimal(1.02).setScale(2, BigDecimal.ROUND_UP));
            BigDecimal a = new BigDecimal(1.02);
            System.out.println(a.scale());
            System.out.println(a.scale() == 2);
        }
    }

    *****************************以下是彩蛋*******************

    使用反射,我们还可以对接口请求对象和系统返回对象的值进行一一比较:

    前提条件:两个对象要进行比较的对象属性名要一致!!!!!

    /**
         * @return void
         * @Author 田海超
         * @Description //TODO 校验结算金额正确性
         * @Date 11:14 2019/12/13
         * @Param [vo, resVo]
         **/
        public void verifyAmount(RequestObjectDemoVO_1 vo, RequestObjectDemoVO_2 resVo) throws Exception{
            Field[] fields = vo.getClass().getDeclaredFields();
            Class c = resVo.getClass();
            for (Field field : fields) {
                if (field.isAnnotationPresent(ParamNotNull.class)) {
                    field.setAccessible(true);
                    int digit = field.getAnnotation(ParamNotNull.class).bigDecimalDigit();
                    if (digit != -1) {// 金额类型--注解类ParamNotNull中的默认值是-1,不等于-1说明配置了小数位数,表明是金额字段
                        Object value = field.get(vo);
                        // 根据循环属性列表的属性名称获得要比较的对象属性Field对信息
                        Field resVoField = c.getDeclaredField(field.getName());
                        resVoField.setAccessible(true);
                        BigDecimal val = (BigDecimal) resVoField.get(resVo);
    //                    System.out.println(val.toPlainString());
                        if (val != null && !val.toPlainString().equals(value)) {
                            String describeName = field.getAnnotation(ParamNotNull.class).describeName();
                            throw new DefinedException(getSimpleResJson("0102", MessageFormat.format("报文内容错误:{0}不正确", describeName)));
                        }
                    }
                }
            }
        }
  • 相关阅读:
    systemctld 启动理解
    公私钥(证书)理解
    布隆过滤器
    python linux下dbg
    iOS基础尺寸图
    metadataObjectTypes 详解
    pkg_config_path 环境变量设置 教程
    Cloning failed using an ssh key for authentication, enter your GitHub credentials to access private 解决方案
    docker php安装GD扩展
    mysql 隔离级别
  • 原文地址:https://www.cnblogs.com/tianhaichao/p/12060008.html
Copyright © 2020-2023  润新知