• java利用注解及反射做通用的入参校验


    一、原理:

      1、做一个field注解,注解有两个参数:是否必填、toString之后的最大长度

      2、对某个request类(或基类),使用注解标记某个字段的校验详情

      3、通用的static方法,利用反射获取属性的值,并做校验。不通过则抛出特定的异常

    二、上代码:

    异常类:

    package com.test;
    
    
    /**
     * 基础异常
     * @author zyydd
     * @date 2019/1/24 10:33
     * @version 1.0.0
     **/
    public class BaseException extends RuntimeException {
    
        /** 异常码 */
        private String code;
        /** 异常描述 */
        private String desc;
    
        public BaseException(){
    
        }
    
        public String getCode() {
            return code;
        }
    
        private void setCode(String code) {
            this.code = code;
        }
    
        public String getDesc() {
            return desc;
        }
    
        private void setDesc(String desc) {
            this.desc = desc;
        }
    
        public BaseException(String code, String desc) {
            this(code, desc, new Throwable(desc));
        }
    
        public BaseException(String code, String desc, Throwable canse) {
            super(new StringBuilder().append("code=").append(code).append(", desc=").append(desc).toString(), canse);
            this.setCode(code);
            this.setDesc(desc);
        }
    
    
        @Override
        public String toString() {
            return new StringBuilder().append(getClass().getName())
                    .append("{code=").append(this.getCode())
                    .append(", desc=").append(this.getDesc())
                    .append("}").toString();
        }
    }

    测试的request类:

    package com.test;
    
    /**
     * @author zyydd
     * @date 2019/6/13 18:29
     */
    public class TestChildRequest {
        /**
         * name
         */
        @ParameterAttr(isNecessary = true, lengthLimit = 10)
        private String name;
    
        /**
         * pin
         */
        @ParameterAttr(lengthLimit = 15)
        private String address;
    
        @ParameterAttr(isNecessary = true)
        private String school;
    
        private String other;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    
        public String getSchool() {
            return school;
        }
    
        public void setSchool(String school) {
            this.school = school;
        }
    
        public String getOther() {
            return other;
        }
    
        public void setOther(String other) {
            this.other = other;
        }
    }

    field校验注解类:

    package com.test;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * @author zyydd
     * @date 2019/6/13 16:52
     */
    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface ParameterAttr {
        /**
         * 是否必须,默认不必须
         *
         * @return
         */
        boolean isNecessary() default false;
    
        /**
         * 属性toSring之后,最大长度
         *
         * @return
         */
        int lengthLimit() default 0;
    
    }

    通用校验工具类及main测试方法:

    package com.test;
    
    import org.apache.commons.lang.StringUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import java.lang.reflect.Field;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    /**
     * @author zyydd
     * @date 2019/6/13 17:02
     */
    public class ParameterCheckUtils {
        private static Logger logger = LoggerFactory.getLogger(ParameterCheckUtils.class);
    
        public static void commonCheck(Object obj) throws IllegalAccessException {
            if (obj == null) {
                logger.error("obj can not be null!");
                throw new BaseException("9999", "obj can not be null!");
            }
    
            List<Field> fieldList = new ArrayList<Field>();
            Class clazz = obj.getClass();
            while (!Object.class.equals(clazz)) {
                fieldList.addAll(Arrays.asList(clazz.getDeclaredFields()));
                clazz = clazz.getSuperclass();
            }
            for (Field field : fieldList) {
                field.setAccessible(true);
                ParameterAttr attr = field.getAnnotation(ParameterAttr.class);
                if (attr == null) {
                    continue;
                }
                Object paramObj = field.get(obj);
                if (attr.isNecessary()) {
                    if (paramObj == null || StringUtils.isBlank(paramObj.toString())) {
                        logger.error("class={} field={} can not be null!", obj.getClass().getName(), field.getName());
                        throw new BaseException("9998", "field=" + field.getName() + " can not be null!");
                    }
                }
                if (attr.lengthLimit() > 0 && paramObj != null && StringUtils.isNotBlank(paramObj.toString())) {
                    if (paramObj.toString().length() > attr.lengthLimit()) {
                        logger.error("class={} field={} length is too long! limit={} but length={}", obj.getClass().getName(), field.getName(), attr.lengthLimit(), paramObj.toString().length());
                        throw new BaseException("9997", "field=" + field.getName() + " length is too long!");
                    }
                }
            }
            logger.info("commonCheck success!");
        }
    
        public static void main(String[] args) throws IllegalAccessException {
            //正常数据
            TestChildRequest request1 = new TestChildRequest();
            request1.setName("王钢蛋");
            request1.setAddress("aabbccddeeaabbc");
            request1.setSchool("北京市智障二中");
            ParameterCheckUtils.commonCheck(request1);
    
            //为空数据
            try {
                ParameterCheckUtils.commonCheck(null);
            } catch (Exception e) {
                logger.error("error1 ", e);
    
            }
            //必填没传的数据
            try {
                TestChildRequest request2 = new TestChildRequest();
                request2.setName("王钢蛋");
                request2.setAddress("aabbccddeeaabbc");
                ParameterCheckUtils.commonCheck(request2);
            } catch (Exception e) {
                logger.error("error2 ", e);
            }
    
            //字段超长的数据
            try {
                TestChildRequest request3 = new TestChildRequest();
                request3.setName("王钢蛋");
                request3.setAddress("aabbccddeeaabbcc");
                request3.setSchool("北京市智障二中");
                ParameterCheckUtils.commonCheck(request3);
            } catch (Exception e) {
                logger.error("error3 ", e);
            }
        }
    
    }

    执行结果:

  • 相关阅读:
    Android 音视频同步机制
    FFmpeg命令行工具学习(五):FFmpeg 调整音视频播放速度
    Android框架式编程之RxJava
    Android Gradle 学习笔记(一):Gradle 入门
    FFmpeg开发实战(六):使用 FFmpeg 将YUV数据编码为视频文件
    SDL 开发实战(七): SDL 多线程与锁机制
    JNI实战(四):C 调用 Java
    JNI实战(三):JNI 数据类型映射
    JNI实战(二):Java 调用 C
    JNI实战(一):JNI HelloWorld
  • 原文地址:https://www.cnblogs.com/zhenyuyaodidiao/p/12015542.html
Copyright © 2020-2023  润新知