深圳幻海软件技术有限公司 欢迎您!

使用Spring的AOP打印HTTP接口出入参日志

2023-02-28

前言最近在维护一个运营端的系统,和前端联调的过程中,经常需要排查一些交互上的问题,每次都得看前端代码的传参和后端代码的出参,于是打算给HTTP接口加上出入参日志。但看着目前的HTTP接口有点多,那么有什么快捷的方式呢?答案就是实用Spring的AOP功能,简单实用。思路定义个一个SpringAOP的

前言

最近在维护一个运营端的系统,和前端联调的过程中,经常需要排查一些交互上的问题,每次都得看前端代码的传参和后端代码的出参,于是打算给HTTP接口加上出入参日志。

但看着目前的HTTP接口有点多,那么有什么快捷的方式呢?答案就是实用Spring的AOP功能,简单实用。

思路

定义个一个SpringAOP的配置类,里边获取请求的URL、请求的入参、相应的出参,通过日志打印出来。

SpringBoot的aop依赖:

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
  • 1.
  • 2.
  • 3.
  • 4.

示例

1.编写一个HTTP接口

定义了一个Controller,里边就一个方法,方法请求类型是get,出入参都是简单的一个字符串字段。

package com.example.springbootaoplog.controller;


import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author hongcunlin
 */
@RestController
@RequestMapping("/index")
public class IndexController {

    @GetMapping("/indexContent")
    public String indexContent(String param) {
        return "test";
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.

2.编写一个AOP日志配置

这算是本文的重点了,定义一个AOP的内容,首先是切点,再者是请求前日志打印,最后请求后日志打印

package com.example.springbootaoplog.config;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
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.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

/**
 * aop日志打印配置
 *
 * @author hongcunlin
 */
@Slf4j
@Aspect
@Component
public class AopLogConfig {
    /**
     * 切点路径:Controller层的所有方法
     */
    @Pointcut("execution(public * com.example.springbootaoplog.controller.*.*(..))")
    public void methodPath() {
    }

    /**
     * 入参
     *
     * @param joinPoint 切点
     */
    @Before(value = "methodPath()")
    public void before(JoinPoint joinPoint) {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        String url = requestAttributes.getRequest().getRequestURL().toString();
        log.info("请求 = {}, 入参 = {}", url, JSON.toJSONString(joinPoint.getArgs()));
    }

    /**
     * 出参
     *
     * @param res 返回
     */
    @AfterReturning(returning = "res", pointcut = "methodPath()")
    public void after(Object res) {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        String url = requestAttributes.getRequest().getRequestURL().toString();
        log.info("请求 = {}, 入参 = {}", url, JSON.toJSONString(res));
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.

3.结果测试

我们通过浏览器的URL,针对我们编写的http接口,发起一次get请求:

可以看到,日志里边打印了我们预期的请求的URL和出入参了:

说明我们的程序是正确的了。

最后

本文分享了通过Spring的AOP功能,完成HTTP接口的出入参日志的打印的方法,同时也说明,越是基础的东西,越是实用。