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();
    }
}

 

posted @ 2020-02-03 10:53  叮叮叮叮叮叮当  阅读(254)  评论(0编辑  收藏  举报