关于AOP的@Around特殊处理RequestBody的使用小结

本文介绍了如何在Springboot项目中使用AOP进行请求参数的处理,通过Controller方法和RequestConverter切面,实现在API处理过程中将用户请求的A转换为B,但响应中仍保持A的形式。作者还提供了具体的代码示例和测试案例。
摘要由CSDN通过智能技术生成

目录

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。

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值