目录
1. 概述
1.1 背景
1.2 源码
2. 测试
2.1 Controller
2.2 SpecialName配置
2.3 RequestConverter
2.4 测试
最近项目上遇到一个这样的需求:用户请求的时候传过来A,在api处理过程中要把A当成B去处理,但是返回的标识中又必须是A作为response的一部分。
举个例子就是A和B的权限是一样,所以当api处理过程中当作B去处理。
于是在这会需要用到Aspect去做切面处理,以下做了一些总结。
1. 概述
1.1 背景
以下通过一个简单的Springboot项目的api去测试这个逻辑过程。
关于AOP获取RequestBody参数更复杂的处理可以参考:
SpringBoot AOP获取@RequestBody参数_springboot获取body参数-CSDN博客
日志管理模块使用Aop使用Request获得前端的传参_aop获取request-CSDN博客
1.2 源码
Git地址:https://github.com/BAStriver/springboot-test/blob/feature/annotation-for-request-params/springboot-jpa-demo/src/main/java/com/bas/controller/UserInfoController.java
2. 测试
2.1 Controller
创建如下的方法,UserInfoDTO其中一个属性是name。
@PostMapping("/test")
@ResponseBody
public UserInfoDTO test(@RequestBody UserInfoDTO user) {
System.out.println("=========test==========");
System.out.println("user: "+user);
return user;
}
2.2 SpecialName配置
com.bas.special.user=T-ABC|ABC,T-EDF|EDF
2.3 RequestConverter
@Aspect
@Configuration
@Slf4j
public class RequestConverter {
@Value("${com.bas.special.user}")
private List<String> specialUsers;
@Pointcut("execution(* com.bas.controller.*Controller.*(..))")
public void executeService() {
}
@Around("executeService()")
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
// parse request body
Map<String, String> userMap = specialUsers.stream().collect(Collectors.toMap(s -> s.split("\\|")[0], s -> s.split("\\|")[1]));
if (userMap.isEmpty())
return pjp.proceed();
Object[] args = pjp.getArgs();
String userName = null;
for (Object arg : args) {
log.info("arg: {}", arg);
if (arg instanceof UserInfoDTO) {
UserInfoDTO userInfoDTO = (UserInfoDTO) arg;
if (userMap.containsKey(userInfoDTO.getName())) {
// change to special user name
userName = userInfoDTO.getName();
userInfoDTO.setName(userMap.get(userInfoDTO.getName()));
break;
}
}
}
Object result = pjp.proceed();
// rollback special user name
if (userName != null && result instanceof UserInfoDTO) {
((UserInfoDTO) result).setName(userName);
return result;
} else {
return pjp.proceed();
}
}
}
其中pjp.proceed();是真正调用test()的地方,在这之前,如果name=T-ABC或T-EDF将会分别转成ABC或EDF;proceed()之后在返回response之前再将name赋值回去T-ABC或T-EDF。
2.4 测试
---- curl http://localhost:8080/user/test
{
"name": "T-ABC",
"gender": "boy",
"age": 1
}
如图,api request传入了T-ABC,而test()变成了ABC,然后response返回的是T-ABC。