栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

springboot——日志的切面处理

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

springboot——日志的切面处理

在外界访问资源的时候,需要作日志记录
但不可能在每个controller上面都写一遍日志记录的函数
因此需要使用AOP对controller进行一个日志方法的增强

首先做好springboot的yml配置

logging:
  level:
    root: info
    com.wzyblog: debug
  file:
    name: log/blog-dev.log

步骤:
1、编写日志方法类
2、编写好切面,设置好切点表达式和注解
3、设定需要记录的日志内容
记录{ url;访问源ip;调用方法;传入参数;返回的页面名 }
开整


目录结构如下

我们需要覆盖所有controller
【我这里的所有controller会放到web包下】
代码如下

@Aspect
@Component
public class LogAspect {

    private Logger logger= LoggerFactory.getLogger(this.getClass());

    @Pointcut("execution(* com.wzyblog.web.*.*(..))")
    public void log(){}

    @Before("log()")
    public void doBefore(){
       
    }

    @AfterReturning(returning = "result", pointcut = "log()")
    public void logAfterReturning(Object result){
        
    }

日志嘛,肯定需要写日志的一个对象

    private Logger logger= LoggerFactory.getLogger(this.getClass());

编写一个内部类,包含{ url;访问源ip;调用方法;传入参数;返回的页面名 }
编写其全参构造函数以及tostring方法【用lombok也可】

 
    private class content{
        private String url;
        private String ip;
        private String method;
        private Object[] args;

        public content(String url, String ip, String method, Object[] args) {
            this.url = url;
            this.ip = ip;
            this.method = method;
            this.args = args;
        }

        @Override
        public String toString() {
            return "{" +
                    "url='" + url + ''' +
                    ", ip='" + ip + ''' +
                    ", method='" + method + ''' +
                    ", args=" + Arrays.toString(args) +
                    '}';
        }
    }
Question

url和访问源ip如何获得呢?
我们可以在请求域中获取
先得到一个servletrequestattributes对象
再从中取出所需要的httpservletrequest对象
调用其中的两个方法即可获取url与ip
【其中getrequestURL方法返回的类型是stringbuffer】

		ServletRequestAttributes attributes= (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        String url=request.getRequestURL().toString();
        String ip=request.getRemoteAddr();

调用方法和传入参数又如何获取呢?
此时则需要使用一个aop特有的对象【joinpoint】
dobefore函数传入一个joinpoint对象
调用此对象的两个函数即可获取所要数据

		String method=
                joinPoint.getSignature().getDeclaringTypeName()
                +"."+
                joinPoint.getSignature().getClass();

        Object[] args=joinPoint.getArgs();

再将这四个参数利用内部类的有参构造创建content对象
最后写入日志

		content content = new content(url,ip,method,args);
        logger.info("Request:{}",content);

最后返回的页面名称如何获取?
使用afterreturning注解
这个注解可以获取切面方法的返回值
controller的返回值恰好是html文件名【无改动前后缀的情况下】

@AfterReturning(returning = "result", pointcut = "log()")
    public void logAfterReturning(Object result){
        logger.info("Result:{}",result);
//        记录最后返回的是哪个页面
    }

编写完之后的代码如下
@Aspect
@Component
public class LogAspect {

    private Logger logger= LoggerFactory.getLogger(this.getClass());

    @Pointcut("execution(* com.wzyblog.web.*.*(..))")
    public void log(){}

    @Before("log()")
    public void doBefore(JoinPoint joinPoint){
        //                传入的是切面对象,即出发这个AOP时被调用的那个方法,以获取所需要的"调用方法"以及"传入参数"
        ServletRequestAttributes attributes= (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        String url=request.getRequestURL().toString();
        String ip=request.getRemoteAddr();

        String method=
                joinPoint.getSignature().getDeclaringTypeName()
                +"."+
                joinPoint.getSignature().getClass();

        Object[] args=joinPoint.getArgs();

        content content = new content(url,ip,method,args);
        logger.info("Request:{}",content);
    }

    @AfterReturning(returning = "result", pointcut = "log()")
    public void logAfterReturning(Object result){
        logger.info("Result:{}",result);
//        记录最后返回的是哪个页面
    }



    
    private class content{
        private String url;
        private String ip;
        private String method;
        private Object[] args;

        public content(String url, String ip, String method, Object[] args) {
            this.url = url;
            this.ip = ip;
            this.method = method;
            this.args = args;
        }

        @Override
        public String toString() {
            return "{" +
                    "url='" + url + ''' +
                    ", ip='" + ip + ''' +
                    ", method='" + method + ''' +
                    ", args=" + Arrays.toString(args) +
                    '}';
        }
    }
}

最后的测试略

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/353461.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号