切面整合自定义注解,对接口请求参数进行校验

  1. jar包依赖
           aspectj          : "org.aspectj:aspectjweaver:1.9.6",		
  1. 自定义注解并设置需要校验的字段
@Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface StoreIdValid {

   String storeId() default "";
}
  1. 解析注解
@Component
public class AnnotationResolver {

   private static AnnotationResolver resolver;

   public static AnnotationResolver newInstance() {

       if (resolver == null) {
           return resolver = new AnnotationResolver();
       } else {
           return resolver;
       }

   }


   /**
    * 解析注解上的值
    *
    * @param joinPoint
    * @param str       需要解析的字符串
    * @return
    */
   public Object resolver(JoinPoint joinPoint, String str) {

       if (str == null) {
           return null;
       }
       Object value = null;
       // 如果name匹配上了#,则把内容当作变量
       if (str.matches("#\\D*")) {
           String newStr = str.replaceAll("#", "").replaceAll("", "");
           // 复杂类型
           if (newStr.contains(".")) {
               try {
                   value = complexResolver(joinPoint, newStr);
               } catch (Exception e) {
                   e.printStackTrace();
               }
           } else {
               value = simpleResolver(joinPoint, newStr);
           }
       } else { //非变量
           value = str;
       }
       return value;
   }


   private Object complexResolver(JoinPoint joinPoint, String str) throws Exception {

       MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();

       String[] names = methodSignature.getParameterNames();
       Object[] args = joinPoint.getArgs();
       String[] strs = str.split("\\.");

       for (int i = 0; i < names.length; i++) {
           if (strs[0].equals(names[i])) {
               Object obj = args[i];
               Method dmethod = obj.getClass().getDeclaredMethod(getMethodName(strs[1]), null);
               Object value = dmethod.invoke(args[i]);
               return getValue(value, 1, strs);
           }
       }

       return null;

   }

   private Object getValue(Object obj, int index, String[] strs) {

       try {
           if (obj != null && index < strs.length - 1) {
               Method method = obj.getClass().getDeclaredMethod(getMethodName(strs[index + 1]), null);
               obj = method.invoke(obj);
               getValue(obj, index + 1, strs);
           }

           return obj;

       } catch (Exception e) {
           e.printStackTrace();
           return null;
       }
   }

   private String getMethodName(String name) {
       return "get" + name.replaceFirst(name.substring(0, 1), name.substring(0, 1).toUpperCase());
   }


   private Object simpleResolver(JoinPoint joinPoint, String str) {
       MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
       String[] names = methodSignature.getParameterNames();
       Object[] args = joinPoint.getArgs();

       for (int i = 0; i < names.length; i++) {
           if (str.equals(names[i])) {
               return args[i];
           }
       }
       return null;
   }
}

4.使用切面拦截

@Aspect
@Component
public class StoreIdAspect {

    private static final Logger logger = LoggerFactory.getLogger(StoreIdAspect.class);

    @Resource
    private AnnotationResolver annotationResolver;

    /**
     * 切入点
     */
    @Pointcut("@annotation(******.StoreIdValid)")
    public void cut() {}

    /**
     * 前置
     * @param joinPoint
     */
    @Before("cut()")
    public void beforePointCut(JoinPoint joinPoint) {
        Object[] args = joinPoint.getArgs();
        String jsonString = JSON.toJSONString(args);
        logger.info("接口入参:{}",jsonString);
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        StoreIdValid annotation = signature.getMethod().getAnnotation(StoreIdValid.class);
        // 通过AnnotationResolve解析注解属性参数
        AnnotationResolver annotationResolver = AnnotationResolver.newInstance();
        Object paramObj = annotationResolver.resolver(joinPoint, annotation.storeId());
        Long storeId = (Long) paramObj;
        // 通过storeId查询到store对象是否是权限下的storeId
        if (!AuthenticationInterceptor.STORE_LIST.get().contains(storeId)) {
            throw new GlobalException(CodeEnum.STOREID_NOT_EXIST);
        }
    }

	// 对接口数据加密,与当前校验参数功能无关
    @Around("@annotation(********.EncryptData)")
    public Response<String> afterReturningPointCut(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Response proceed = (Response)proceedingJoinPoint.proceed();
        String data = (String)proceed.getData();
        logger.info("返回数据加密前:{}",data);
        String commonsecret = AuthenticationInterceptor.COMMON_SECRET.get();
        data = EncryptUtil.encrypt(data, commonsecret);
        logger.info("返回数据加密后:{}",data);
        proceed.setData(data);
        return proceed;
    }
}
  1. 在需要校验参数的接口上加上注解
    在这里插入图片描述通过@StoreIdValid注解里面的storeId = #dto.storeId可以获取到当前请求dto内的字段storeId的值,并且在切面中对其进行校验!
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值