基于AOP实现接口请求的入参和返回日志打印

在开发中,为提高问题排查效率,文章提出了使用Aop来自动记录接口入参和返回日志。通过@Aspect、@Component和@Slf4j注解,定义切入点并分别在方法前后插入日志打印,包括请求URI、参数、响应信息及请求耗时,从而简化二次操作和减少处理时间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景:

        鉴于日常开发过程中,很多排查问题的情况下,需要二次操作业务流程进行入参的获取,实际操作起来增加排查问题的处理时间,为了提高效率,可以通过Aop实现接口入参以及返回的日志打印,方便快速解决问题。

上代码:

@Aspect
@Component
@Slf4j
public class LogAspect {

    //用来记录请求进入的时间,防止多线程时出错,这里用了ThreadLocal
    ThreadLocal<Long> startTime = new ThreadLocal<>();

    /**
     * 定义切入点
     */
    @Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping) || @annotation(org.springframework" +
            ".web.bind.annotation.PostMapping)  || @annotation(org.springframework.web.bind.annotation.GetMapping) ")
    public void requestLog() {
    }

    /**
     * 方法之前执行,日志打印请求信息
     *
     * @param joinPoint joinPoint
     */

    @Before("requestLog()")
    public void doBefore(JoinPoint joinPoint) {
        startTime.set(System.currentTimeMillis());
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
        HttpServletRequest request = servletRequestAttributes.getRequest();
        Object[] args = joinPoint.getArgs();
        Object[] params = new Object[args.length];
        for (int i = 0; i< args.length;i++) {
            if (!(args[i] instanceof HttpServletRequest) && !(args[i] instanceof HttpServletResponse) && !(args[i] instanceof MultipartFile)) {
                params[i]=args[i];
            }
        }
        //打印当前的请求路径,请求参数,如果需要打印其他的信息可以到request中去拿
        log.info("【请求参数】:{} ,RequestParam:{}", request.getRequestURI(), JSON.toJSON(params));
    }


    /**
     * 方法返回之前执行,打印才返回值以及方法消耗时间
     *
     * @param response 返回值
     */

    @AfterReturning(returning = "response", pointcut = "requestLog()")
    public void doAfterRunning(Object response) {
        //打印返回值信息
        log.info("【响应返回】:{}   ", JSON.toJSON(response));
        //打印请求耗时
        log.info("【本次请求响应时间】: [{}ms]", System.currentTimeMillis() - startTime.get());
    }

}

### 请求日志输出的AOP工具类实现 在Spring Boot中,可以通过AOP(Aspect-Oriented Programming)技术实现请求日志记录功能。下面是一个完整的示例代码,展示如何创建一个AOP切面来拦截控制器中的方法调用,并将请求返回值记录到日志中。 #### 切面类实现 以下是基于Spring AOP的一个简单切面类,用于捕获HTTP请求打印其输返回结果: ```java import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @Aspect @Component public class LoggingAspect { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Before("@annotation(org.springframework.web.bind.annotation.RequestMapping)") public void logRequest(JoinPoint joinPoint) { String className = joinPoint.getTarget().getClass().getName(); String methodName = joinPoint.getSignature().getName(); Object[] args = joinPoint.getArgs(); StringBuilder sb = new StringBuilder(); for (Object arg : args) { sb.append(arg).append(" "); } logger.info("Class Name: {}, Method Name: {}, Arguments: {}", className, methodName, sb.toString()); } @AfterReturning(pointcut = "@annotation(org.springframework.web.bind.annotation.RequestMapping)", returning = "result") public void logResponse(Object result) { logger.info("Response Data: {}", result); } } ``` 上述代码实现了两个主要的功能: 1. **`logRequest` 方法**:在任何带有 `@RequestMapping` 注解方法被调用之前触发,记录目标类名、方法名称及其传数[^1]。 2. **`logResponse` 方法**:在带 `@RequestMapping` 的方法成功执行之后触发,记录该方法返回值。 #### 配置依赖项 为了使上面的代码正常工作,需要确保项目的pom.xml文件中有如下Maven依赖项: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> </dependency> ``` 这些依赖分别引了Spring AOP支持以及Logback作为日志框架[^3]。 #### 测试场景 假设存在这样一个简单的RESTful服务接口: ```java @RestController @RequestMapping("/api/test") public class TestController { @GetMapping("/hello") public String sayHello(@RequestParam(value="name", defaultValue="World") String name){ return String.format("Hello %s!", name); } } ``` 当客户端访问 `/api/test/hello?name=Alice` 路径时,LoggingAspect会自动捕捉此请求并将相关信息写日志文件或控制台输出中。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

注。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值