Spring Boot2.x使用AOP进行请求和响应日志的打印

1.导入jar包

加入该包后,spring boot默认就会开启aop了。

<!--aop-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2.配置yml文件

强制使用cglib进行动态代理,默认使用的是Java的动态代理。

spring:
	aop:
	    #使用cglib进行代理
	    proxy-target-class: true

3.编写AOP切面

@Aspect
@Component
public class ControllerRequestAdvice {

    private static final ThreadLocal<Long> timeThreadLocal = new ThreadLocal<Long>();

    public static final Logger logger = LoggerFactory.getLogger(ControllerRequestAdvice.class);

    /**
     * 定义切点
     */
    @Pointcut("execution(public * per.mx.xxx.controller.*.*(..))")
    public void log() {

    }

    /**
     * 处理请求前处理
     *
     * @param joinPoint 连接点
     */
    @Before("log()")
    public void doBefore(JoinPoint joinPoint) {
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = servletRequestAttributes.getRequest();
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = methodSignature.getParameterNames();
        Object[] args = joinPoint.getArgs();

        String client = request.getRemoteAddr();
        String method = request.getMethod();
        String requestURI = request.getRequestURI();
        String token = request.getHeader("token");

        long currentTimeMillis = System.currentTimeMillis();
        timeThreadLocal.set(currentTimeMillis);

        Map<String, Object> params = new HashMap<>();
        for (int i = 0; i < parameterNames.length; i++) {
            String parameterName = parameterNames[i];
            Object parameterValue = args[i];
            if (parameterValue instanceof MultipartFile) {
                Map<String, Object> f = getFileParam((MultipartFile) parameterValue);
                params.put(parameterName, f);
                continue;
            }
            params.put(parameterName, parameterValue);
        }

        StringBuffer sb = new StringBuffer();
        sb.append("Request_").append(currentTimeMillis).append(" ");
        sb.append("<").append(client).append(">");
        sb.append(" ").append(method).append(" ");
        sb.append("\"").append(requestURI).append("\"");
        sb.append(" token:").append(token).append(" ");
        sb.append("params").append("=>").append(JSON.toJSONString(params));

        logger.info(sb.toString());
    }

    /**
     * 处理请求后返回
     *
     * @param obj 返回值
     */
    @AfterReturning(pointcut = "log()", returning = "obj")
    public void afterReturning(Object obj) {
        logger.info("Response_" + timeThreadLocal.get() + " => " + JSON.toJSONString(obj));
    }

    private Map<String, Object> getFileParam(MultipartFile file) {
        Map<String, Object> params = new HashMap<>();
        params.put("文件名", file.getOriginalFilename());
        params.put("文件类型", file.getContentType());
        params.put("文件大小", FileUtil.getFileSize(file.getSize()));
        return params;
    }
}

4、日志切面的优化

@Aspect
@Component
public class ControllerRequestAdvice {

    private static final ThreadLocal<Long> timeThreadLocal = new ThreadLocal<Long>();

    public static final Logger logger = LoggerFactory.getLogger(ControllerRequestAdvice.class);

    /**
     * 定义切点
     */
    @Pointcut("execution(public * per.mx.xx.controller.*.*(..))")
    public void log() {

    }

    /**
     * 处理请求前处理
     *
     * @param joinPoint 连接点
     */
    @Before("log()")
    public void doBefore(JoinPoint joinPoint) {
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = servletRequestAttributes.getRequest();
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = methodSignature.getParameterNames();
        Object[] args = joinPoint.getArgs();

        String client = request.getRemoteAddr();
        String method = request.getMethod();
        String requestURI = request.getRequestURI();
        String token = request.getHeader("token");

        long currentTimeMillis = System.currentTimeMillis();
        timeThreadLocal.set(currentTimeMillis);

        Map<String, Object> params = new HashMap<>();
        for (int i = 0; i < parameterNames.length; i++) {
            String parameterName = parameterNames[i];
            Object parameterValue = args[i];
            if (parameterValue instanceof MultipartFile) {
                Map<String, Object> f = getFileParam((MultipartFile) parameterValue);
                params.put(parameterName, f);
                continue;
            }
            params.put(parameterName, parameterValue);
        }

        StringBuffer sb = new StringBuffer();
        sb.append("Request_").append(currentTimeMillis).append(" ");
        sb.append("<").append(client).append(">");
        sb.append(" ").append(method).append(" ");
        sb.append("\"").append(requestURI).append("\"");
        sb.append(" token:").append(token).append(" ");
        sb.append("params").append("=>").append(JSON.toJSONString(params));

        logger.info(sb.toString());
    }

    /**
     * 处理请求后返回
     *
     * @param obj 返回值
     */
    @AfterReturning(pointcut = "log()", returning = "obj")
    public void afterReturning(Object obj) {
        logger.info("Response_" + timeThreadLocal.get() + " => " + JSON.toJSONString(obj));
    }

    private Map<String, Object> getFileParam(MultipartFile file) {
        Map<String, Object> params = new HashMap<>();
        params.put("文件名", file.getOriginalFilename());
        params.put("文件类型", file.getContentType());
        params.put("文件大小", FileUtil.getFileSize(file.getSize()));
        return params;
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值