controller层统一拦截进行日志处理

author author     2022-09-13     789

关键词:

前言

在项目中添加统一日志时,我们往往会用到aop进行切面处理,常用在controller层添加切面,以处理请求和返回的各项参数数据。

使用切面进行日志处理

下面我们就看一个例子说明基本的使用方式:

package com.ding.test.core.aspect;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

@Aspect
@Component
public class LogAspect {
    private final static Logger LOGGER = LoggerFactory.getLogger(LogAspect.class);
   //定义切点
    @Pointcut("execution(* com.ding..controller.*.*(..))")
    public void printLog() {

    }
    /**
     * 会话ID
     */
    private final static String SESSION_TOKEN_KEY = "sessionTokenId";
    
    @Around("printLog()")
    private Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        long startTime = System.currentTimeMillis();
         String token = java.util.UUID.randomUUID().toString().replaceAll("-", "").toUpperCase();
         MDC. put(SESSION_TOKEN_KEY, token);
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        HttpServletRequest request = sra.getRequest();

        // 获取请求相关信息
        String url = request.getRequestURL().toString();
        String method = request.getMethod();
        String uri = request.getRequestURI();
        String queryString = request.getQueryString();

        // 获取调用方法相信
        Signature signature = pjp.getSignature();
        String className = signature.getDeclaringTypeName();
        String methodName = signature.getName();
    //这里定义log输出的内容,前面是内容格式,{}按照顺序被替换为后面参数的具体值
        LOGGER.info("请求开始, {}#{}() URI: {}, method: {}, URL: {}, params: {}", className, methodName, uri, method, url,
                queryString);
        //result的值就是被拦截方法的返回值
        try {
            //proceed方法是调用实际所拦截的controller中的方法,这里的result为调用方法后的返回值
            Object result = pjp.proceed();
            long endTime = System.currentTimeMillis();
            //定义请求结束时的返回数据,包括调用时间、返回值结果等
            LOGGER.info("请求结束, {}#{}(), URI: {}, method: {}, URL: {}, time: {}ms, result: {} ", className, methodName,
                    uri, method, url, (endTime - startTime), result);
            return result;
        } catch (Exception e) {
            long endTime = System.currentTimeMillis();
            LOGGER.error("请求出错, {}#{}(), URI: {}, method: {}, URL: {}, time: {}ms", className, methodName, uri, method,
                    url, (endTime - startTime), e);
            throw e;
        }finally {
            MDC. remove(SESSION_TOKEN_KEY);
        }
    }
}

 

本来spring就自带一套aop实现,我们直接使用此实现即可,本来使用aop还需要定义一些xml文件,但由于我们使用的是spring-boot框架,这一步就省略掉了。也就是说,在spring-boot中,我们可以直接使用aop而不需要任何的配置。

这里我们分析一下上面的示例代码:

@Aspect:描述一个切面类,定义切面类的时候需要打上这个注解

@Component:泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。

@PointCut("execution(* com.ding..controller.*.*(..))"):定义切点,括号内的为拦截的路径,这里指目录下的controller中所以方法

这里定义切点的方法为printLog(),在进行前置通知、后置通知、环绕通知的时候,就可以根据这个方法进行拦截。这里我们用到了环绕通知的方式: @Around("printLog()"),定义后,在进行controller中方法调用时就会先调用这里的doAround方法。方法中的含义在注释中已经写清楚了,可以打断点再看每段代码的具体含义。

后记

本文通过一个案例讲解了一下使用切面进行日志处理的功能,重点在于配置切点、环绕通知、方法调用。这些成功后就按照自己需求进行日志内容的输出了。

==================================================================================

输出倒逼输入,作为技术人员教是最好的学习方法,我是一名爱思考、爱学习、涉猎广泛想搞事情的程序员。

坚持就是娱乐,因为惊喜更重要

==================================================================================

统一异常处理@exceptionhandler(代码片段)

...tionHandler(异常类型.class). 这个注解的功能是:自动捕获controller层出现的指定类型异常,并对该异常进行相应的异常处理. 比如我要在controller层中处理InsertMessageException类型异常,我就可以在controller层的类中定义以下方法:@Except... 查看详情

aop统一处理请求日志

1、添加依赖spring-boot-starter-aop2、建立处理文件 在访问到GirlController中方法之前,拦截所有GirlController中的方法: 只拦截gilrList方法: 在访问到方法之后,打印222222 防止代码重复: 使用logger代替system.out.println&n... 查看详情

springboot+vue博客项目总结(代码片段)

...启动类2.统一异常处理3.登录功能实现3.1接口说明3.2JWT3.3Controller3.4Service3.5登录参数,redis配置5.获取用户信息5.1接口说明5.2Controller5.3Service6.登录拦截器6.1拦截器实现6.2使拦截器生效7.ThreadLocal保存用户信息8.使用线程池更新阅... 查看详情

统一异常处理(代码片段)

...有问题,则向前端返回错误信息。之前的项目里,只有在controller层可以返回错误信息,而在service层,只能返回固定的结果,不能说明错误信息。此时可以通过自定义异常,然后统一处理来解决。对于统一异常,通常有四种解决... 查看详情

分享springbootcontroller统一日志代码

最近项目需要做一个controller层的aop,主要解决下面问题:1.controller日志统一打印输出json格式,兼容json和velocity。2.项目异常处理3.异常邮件发送4.页面访问统计主要思路使用aop实现,controller参数统一使用@RequestParam接收。controller@... 查看详情

springaop对controller层拦截失效问题

参考技术A问题:当使用SpringAOP对Controller层的Controller类的方法进行切面拦截,不起作用。AOP配置没有任何问题。分析:断点调试:Spring源码断点调试,在调用Controller方法时,Controller的实例被JDK进行动态代理了;解决:Spring默认... 查看详情

springboot的四种拦截机制

...。过滤器(filter)拦截器(interceptor)全局异常处理器(ControllerAdvice)切片(aspect)如上图所示,当一个请求发送来的时候,filter在最外层,也最先拦截到请求,接下来就是interceptor,依次是ControllerAdvice(处理controller层异常)... 查看详情

sprongboot——拦截器(代码片段)

...作/***请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)*/@Overr 查看详情

springboot整合aop实现网站访问日志记录(代码片段)

...,而服务层的异常只需要向上抛出即可3、就像Spring中的@Controller、@Service、@Repository注解那样,虽然作用是一样的,但是不同 查看详情

vue前端使用axios统一进行拦截和进行跨域的处理(代码片段)

...面可以创建一个utils或者其他目录,然后在创建一个统一进行拦截的文件api.js2.导入相关的axios和router,以及进行弹框处理的Message的element-ui的组件3.写上你的拦截器跨域处理1.在根目录下面创建一个vue.config.js文件,然后写上... 查看详情

http拦截器-handlerinterceptor(代码片段)

...截器1.preHandle:在业务处理器处理请求之前被调用,调用controller之前调用。预处理,可以进行编码、安全控制、权限校验等处理;2.postHandle:在业务处理器处理请求执行完成后,生成视图之前执行。后处理(调用了Service并返回Mo... 查看详情

springboot2系列教程(十四)|统一异常处理

...的。SpringBoot中的全局异常处理主要起作用的两个注解是@ControllerAdvice和@ExceptionHandler,其中@ControllerAdvice是组件注解,添加了这个注解的类能够拦截Controller的请求,而ExceptionHandler注解可以设置全局处理控制里的异常类型来拦截要... 查看详情

filter记录日志(getpost参数)(代码片段)

...)。你可以使用Interceptor来执行某些任务,例如在Controller处理请求之前编写日志,添加或更新配置……在Spring中,当请求发送到Controller时,在被Controller处理之前,它必须经过Interceptors(0或多个)... 查看详情

filter记录日志(getpost参数)(代码片段)

...)。你可以使用Interceptor来执行某些任务,例如在Controller处理请求之前编写日志,添加或更新配置……在Spring中,当请求发送到Controller时,在被Controller处理之前,它必须经过Interceptors(0或多个)... 查看详情

springboot—集成aop详解(面向切面编程aspect)(代码片段)

...ut)在业务逻辑中进行绑定。比如SpringBoot微服务中的所有controller层需要对http请求进行一些常规日志的打印,如果每次在controller进行打印,代码就会冗余,如果说将这些公共代码进行封装,也需要每一个controller类进行调用,所... 查看详情

springmvc

首先什么是MVCMVC包含Model(模型层)、View(视图层)、Controller(控制层)三层,用户发送请求到Controller,Controller层接受请求、转发请求,委托Model层进行数据处理,Model层(模型层)处理请求,将结果返回给Controller层,Controller... 查看详情

channelhandler

...口,用户可以方便地进行业务逻辑定制,例如打印日志、统一封装异常信息、性能统计和消息编解码等。ChannelHandler支持注解,目前支持的注解 查看详情

添加仓储分类列表接口(service层和controller层)

一、负责顶级分类组请求处理的类:controllerserviceserviceImpl二、负责次级分类请求处理的类:controllerservice serviceImpl三、负责物品总计请求处理的类 controllerservice serviceImpl四、负责日志记录请求处理的类 controller ... 查看详情