AOP:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。
通过使用AOP技术,我们可以在自定义的切面对切点扩展相应的操作,如打印日志,转换参数等。
生产中,为保证数据安全或者减少数据传输量,传递参数时,往往会对参数进行BASE64编码、非对称加密等操作,一般我们会封装一个公共类,需要编解码或加解密参数的时候调用一下,这会造成一定的代码冗余,以上,我们可以采用AOP技术,解放操作。
以对参数进行BASE64编解码为例,我们先定义切面、切点:
/**
* @author : niithub
* @description : 切面-校验请求参数
* @date : 2018/7/20
*/
@Aspect
@Component
@Slf4j
public class ParamAspect {
private static final ObjectMapper MAPPER = new ObjectMapper();
@Pointcut("execution(public * com..*.*Controller.*(..))")
public void doOperation() {
log.info("参数检验AOP");
}
@Around("doOperation()")
public Object doBefore(ProceedingJoinPoint joinPoint) throws Throwable {
Object[] obj = joinPoint.getArgs();
byte[] param = null;
for (Object argItem : obj) {
String convertData;
if (argItem instanceof String) {
param = Base64Utils.decode(String.valueOf(argItem).getBytes());
}
convertData = new String(param);
Map map = MAPPER.readValue(convertData, Map.class);
if(map.get("body") == null) {
throw new ApiRuntimeException(-1, "参数错误");
}
obj[0] = MAPPER.writeValueAsString(map.get("body"));
}
return joinPoint.proceed(obj);
}
@AfterReturning(returning = "object", pointcut = "doOperation()")
public void doAfterReturning(Object object) {
ResponseMessage responseMessage = (ResponseMessage) object;
byte[] a = Base64Utils.encode(String.valueOf(responseMessage.getData()).getBytes());
responseMessage.setMsg(new String(a ));
log.info("请求返回值【{}】", object.toString());
}
}
doBefore方法解码请求参数,doAfterReturning方法编码返回参数。
1. 修改请求参数
请求参数:
打印出的请求参数:
2. 修改返回参数
上图所示,返回参数应该是{"code":0,"msg":"1","data":"2"},实际返回结果:
我们来看下debug过程: