一、前言
在日常开发中,发起请求后,后端常常会因为前端请求参数的不完整而去填充数据,通过分析得到填充的数据Top1的为tenantId(租户Id),此id可以根据token得到用户信息来填充。本次通过AOP的方式来优化这个问题
二、场景再现
2.1 手动填充数据
累计100多次的手动填充,还有一部分会忘记填充参数
三、优化
3.1 定义 AOP 切面
根据对项目请求的分析,此类现象98%出现在Post请求中,本次以PostMapping请求为切入点
@Aspect
@Component
public class RequestParamsLoad {
private static final String PARAMNAME = "tenantId";
@Around("@annotation(org.springframework.web.bind.annotation.PostMapping)")
public Object around(ProceedingJoinPoint point) throws Throwable {
return point.proceed();
}
}
3.2 获取请求参数
@Aspect
@Component
public class RequestParamsLoad {
private static final String PARAMNAME = "tenantId";
@Around("@annotation(org.springframework.web.bind.annotation.PostMapping)")
public Object around(ProceedingJoinPoint point) throws Throwable {
UserVo user = RedisUtils.getUser();
if (point.getArgs().length > 0) {
MethodSignature signature = (MethodSignature) point.getSignature();
HandlerMethod handlerMethod = new HandlerMethod(point.getTarget(), signature.getMethod());
MethodParameter[] methodParameters = handlerMethod.getMethodParameters();
}
return point.proceed();
}
}
3.3 过滤请求参数
@Aspect
@Component
public class RequestParamsLoad {
private static final String PARAMNAME = "tenantId";
@Around("@annotation(org.springframework.web.bind.annotation.PostMapping)")
public Object around(ProceedingJoinPoint point) throws Throwable {
UserVo user = RedisUtils.getUser();
if (point.getArgs().length > 0) {
MethodSignature signature = (MethodSignature) point.getSignature();
HandlerMethod handlerMethod = new HandlerMethod(point.getTarget(), signature.getMethod());
MethodParameter[] methodParameters = handlerMethod.getMethodParameters();
for (MethodParameter parameter : methodParameters) {
try {
Class<?> aClass = point.getArgs()[parameter.getParameterIndex()].getClass();
Class<?> superclass = aClass.getSuperclass();
boolean aFields = Arrays.asList(aClass.getDeclaredFields()).stream().map(f -> f.getName()).collect(Collectors.toList()).contains(PARAMNAME);
boolean sFields = Arrays.asList(superclass.getDeclaredFields()).stream().map(f -> f.getName()).collect(Collectors.toList()).contains(PARAMNAME);
if (aFields || sFields){
Field traceId = aFields ? aClass.getDeclaredField(PARAMNAME) : superclass.getDeclaredField(PARAMNAME);
traceId.setAccessible(true);
traceId.set(point.getArgs()[parameter.getParameterIndex()], user.getTenantId());
}
} catch (Exception e) {
return point.proceed();
}
}
}
return point.proceed();
}