在前后端接口开发过程中,我们常常需要对某些字段进行加解密。以下是使用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;}
}