• AOP参数校验


     

    1、切面依赖

    <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-aop</artifactId>
     </dependency>
    

    2、工具类

    /**
     * @author LiuHuan
     * @date 2019-11-14 21:07
     * @desc 切面工具
     */
    public class AspectUtil {
    
        /**
         * 参数校验
         * @param args
         * @param method
         */
        public static List<String> checkParam(Object[] args, Method method){
            List<String> errorMsgList = Lists.newArrayList();
            if (null == args || 0 == args.length || null == method) {
                return errorMsgList;
            }
    
            Annotation[][] parameterAnnotations = method.getParameterAnnotations();
    
            int index = 0;
            for (Annotation[] parameterAnnotation : parameterAnnotations) {
                Object arg = args[index++];
                for (Annotation annotation : parameterAnnotation) {
                    if (annotation instanceof NotNull) {
                        if (null == arg) {
                            NotNull notNull = (NotNull)annotation;
                            errorMsgList.add(notNull.name() + notNull.msg());
                        }
                    } else if (annotation instanceof NotEmpty) {
                        if (checkArgEmpty(arg)) {
                            NotEmpty notEmpty = (NotEmpty)annotation;
                            errorMsgList.add(notEmpty.name() + notEmpty.msg());
                        }
                    } else if (annotation instanceof VerifyBean) {
                        errorMsgList.addAll(checkBean(arg,((VerifyBean)annotation)));
                    }
                }
            }
    
            return errorMsgList;
    
        }
    
        /**
         * 校验参数是否为empty
         * @param arg
         * @return
         */
        private static boolean checkArgEmpty(Object arg) {
            return null == arg || arg instanceof String && ((String)arg).isEmpty() ||
                                arg instanceof Collection && ((Collection)arg).isEmpty() ||
                                arg instanceof Map && ((Map)arg).isEmpty();
        }
    
    
        /**
         * 校验bean属性参数合法性
         * @param bean
         * @param verifyBean
         * @return
         */
        private static List<String> checkBean(Object bean, VerifyBean verifyBean) {
            List<String> errorMsg = Lists.newArrayList();
            if (null == bean) {
                errorMsg.add(verifyBean.name() + verifyBean.msg());
                return errorMsg;
            }
    
            List<Field> fields = getFields(bean.getClass());
    
            //校验bean中的每个参数合法性
            for (Field field : fields) {
                Annotation[] annotations = field.getDeclaredAnnotations();
                if (null == annotations || 0 == annotations.length) {
                    continue;
                }
    
                field.setAccessible(true);
                Object value = null;
                try {
                    value = field.get(bean);
                } catch (IllegalAccessException e) {
                    //异常不做处理,取null
                }
    
                for (Annotation annotation : annotations) {
                    if (annotation instanceof NotNull && checkNotNull((NotNull)annotation,verifyBean.type(),value)) {
                        NotNull notNull = (NotNull)annotation;
                        errorMsg.add(field.getName() + notNull.msg());
                    } else if (annotation instanceof NotEmpty && checkNotEmpty((NotEmpty)annotation,verifyBean.type(),value)) {
                        NotEmpty notEmpty = (NotEmpty)annotation;
                        errorMsg.add(field.getName() + notEmpty.msg());
                    }
                }
    
            }
    
            return errorMsg;
    
        }
    
        /**
         * 判断在请求类型相符的情况下参数是否为空
         * @param annotation
         * @param type
         * @param value
         * @return
         */
        private static boolean checkNotEmpty(NotEmpty annotation, ServiceTypeEnum type, Object value) {
            for (ServiceTypeEnum serviceTypeEnum : annotation.type()) {
                if (serviceTypeEnum.equals(type) || serviceTypeEnum.equals(ServiceTypeEnum.ALL)) {
                    return checkArgEmpty(value);
                }
            }
            return false;
        }
    
        /**
         * 判断在请求类型相符的情况下参数是否为null
         * @param annotation
         * @param type
         * @param value
         * @return
         */
        private static boolean checkNotNull(NotNull annotation, ServiceTypeEnum type, Object value) {
            for (ServiceTypeEnum serviceTypeEnum : annotation.type()) {
                if (serviceTypeEnum.equals(type) || serviceTypeEnum.equals(ServiceTypeEnum.ALL)) {
                    return null == value;
                }
            }
            return false;
        }
    
        /**
         * 获取该类所有属性
         * @param clazz
         * @return
         */
        private static List<Field> getFields(Class<?> clazz) {
            List<Field> fields = Lists.newArrayList();
    
            //获取父类属性
            Class<?> superclass = clazz.getSuperclass();
            if (null != superclass) {
                List<Field> supperFields = getFields(superclass);
                fields.addAll(supperFields);
            }
    
            Field[] declaredFields = clazz.getDeclaredFields();
            fields.addAll(Arrays.asList(declaredFields));
            return fields;
        }
    }
    

    3、切面

    /**
     * @author LiuHuan
     * @date 2019-11-14 21:15
     * @desc 数据校验切面
     */
    @Component
    @Aspect
    public class RequestParamAspect {
    
        private static Logger logger = LoggerFactory.getLogger(RequestParamAspect.class);
    
        @Pointcut("execution(* com.cainiao.finance.customer.facade.api.*.*(..))")
        public void serviceBefore(){}
    
        /**
         * 方法执行前校验参数合法性
         * @param point
         */
        @Before("serviceBefore()")
        public void before(JoinPoint point){
            Method method = ((MethodSignature)point.getSignature()).getMethod();
            List<String> errorList = AspectUtil.checkParam(point.getArgs(), method);
            if (!errorList.isEmpty()) {
                logger.error("{}#{} param invalid, reason:{}",method.getDeclaringClass().getSimpleName(), method.getName(), errorList.toString());
                throw new ParamException(errorList);
            }
        }
    }
    

    4、注解

    /**
     * @author LiuHuan
     * @date 2019-11-14 21:06
     * @desc 字段非空校验
     */
    @Target(value = {ElementType.FIELD,ElementType.PARAMETER})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface NotEmpty {
    
        ServiceTypeEnum[] type() default {ServiceTypeEnum.ALL};
    
        /**
         * 参数名
         * @return
         */
        String name() default "";
    
        /**
         * 报错信息
         * @return
         */
        String msg() default "不能为空";
    
    }
    
    /**
     * @author LiuHuan
     * @date 2019-11-14 21:06
     * @desc 字段非null校验
     */
    @Target(value = {ElementType.FIELD,ElementType.PARAMETER})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface NotNull {
    
        ServiceTypeEnum[] type() default {ServiceTypeEnum.ALL};
    
        /**
         * 参数名
         * @return
         */
        String name() default "";
    
        /**
         * 报错信息
         * @return
         */
        String msg() default "不能为空";
    }
    
    /**
     * @author LiuHuan
     * @date 2019-11-14 21:06
     * @desc bean校验
     */
    @Target(value = {ElementType.PARAMETER})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface VerifyBean {
    
        /**
         * 校验类型
         * @return
         */
        ServiceTypeEnum type() default ServiceTypeEnum.ALL;
    
        /**
         * 参数名
         * @return
         */
        String name();
    
        /**
         * 报错信息
         * @return
         */
        String msg() default "不能为空";
    }
    

    5、枚举

    /**
     * @author LiuHuan
     * @date 2019-11-14 21:52
     * @desc 请求类型枚举
     */
    public enum ServiceTypeEnum {
    
        /**
         * 所有
         */
        ALL,
        /**
         * 新增
         */
        INSERT,
        /**
         * 删除
         */
        DELETE,
        /**
         * 修改
         */
        UPDATE
    
    }
    

    6、异常

    /**
     * @author LiuHuan
     * @date 2019-11-15 10:03
     * @desc 参数异常
     */
    public class ParamException extends RuntimeException{
    
        private List<String> errorList;
    
        public ParamException(List<String> errorList) {
            this.errorList = errorList;
        }
    
        public List<String> getErrorList() {
            return errorList;
        }
    
        public void setErrorList(List<String> errorList) {
            this.errorList = errorList;
        }
    
        @Override
        public String getMessage() {
            return errorList.toString();
        }
    }
    
  • 相关阅读:
    mac访达中的位置
    ResponseEntity和@ResponseBody以及@ResponseStatus区别
    Spring Boot中进行Junit测试
    添加数据库时出现time zone无法识别问题
    HTTPS
    表达式求值
    《进击JavaScript核心》学习笔记
    GitLab领取任务+建立分支+本地修改+上传分支+合并分支详细步骤
    黑苹果使用感受和常见问题注意事项!
    JS进阶练习
  • 原文地址:https://www.cnblogs.com/ding-dang/p/12254846.html
Copyright © 2020-2023  润新知