springMvc的Aop解析并修改参数

        在前后端接口开发过程中,我们常常需要对某些字段进行加解密。以下是使用Aop对接口的get参数做修改的过程:

自定义注解

AesMethod:只能用于方法

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AesMethod {
}

AesParam:只用用户属性

@Retention(RetentionPolicy.RUNTIME)
@Target(value = ElementType.PARAMETER)
public @interface AesParam {
}

切面

这里必须使用环绕 @Around,这样才能使用转换后参数

@Aspect
@Component
public class AesParamAspect {

   @Around(value = "com.zsc.test.aop.AesParamAspect.aesPointCut()")
    public Object dealAesParam(ProceedingJoinPoint joinPoint) throws Throwable {

        Object[] args = joinPoint.getArgs();
        // 方法签名
        Signature signature = joinPoint.getSignature();
        // 获取代理对象的method方法
        Method proxyMethod = ((MethodSignature)signature).getMethod();
        Annotation[] methodAnnotations = proxyMethod.getDeclaredAnnotations();
        
        //是否是需要解密的方法
        boolean isContainTargetAnnotation = false;
        for(Annotation annotation : methodAnnotations){
            if(annotation.annotationType().getSimpleName().equals("AesParamMethod")){
                isContainTargetAnnotation = true;
            }
        }
        
        if(isContainTargetAnnotation) {
            // 获取目标对象上的method方法(防止有protected或private修饰的方法反射获取失败)
            Method targetMethod = joinPoint.getTarget().getClass().getDeclaredMethod(signature.getName(), proxyMethod.getParameterTypes());

            int num = -1;
            // 取出对应的注解 二维数组,第一维是方法的参数列表,第二维是参数上的注解列表
            Annotation[][] parameterAnnotations = targetMethod.getParameterAnnotations();
            for (Annotation[] annotations : parameterAnnotations) {
                // 获取参数索引位置
                num = num + 1;
                for (Annotation annotation : annotations) {
                    if (annotation.annotationType().getSimpleName().equals("AesParam")) {
                        // 需要做数据解密
                        if (ObjectUtil.isNotEmpty(args[num])) {
                            try {
                                //解密后的数据
                                args[num] += AesUtil.deal(args[num]);
                            } catch (Throwable e) {
                                e.printStackTrace();
                            }
                        }
                    }

                }
            }
        }
        return joinPoint.proceed(args);
    }

    /**
     * 切点
     */
    @Pointcut("execution(* com.zsc.test.controller..*.*(..)) && @annotation(com.zsc.test.annotations.AesMethod)")
    public void aesPointCut(){

    }

测试类

@RestController
@RequestMapping("test")
public class TestController {

    @AesMethod
    @GetMapping("/get")
    public String test(@AesParam @RequestParam("name") String name){
        LOGGER.info("name: {}", name);
        return name;
    }
}

你可能感兴趣的:(java,#,spring,java,切面,springMVC)