• 033 SSM综合练习09--数据后台管理系统--基于AOP的日志处理


    1.数据库与表结构

    (1)日志表信息描述sysLog

    (2)Sql语句

    CREATE TABLE sysLog (
        id VARCHAR2 ( 32 ) DEFAULT SYS_GUID () PRIMARY KEY,
        visitTime timestamp,
        username VARCHAR2 ( 50 ),
        ip VARCHAR2 ( 30 ),
        url VARCHAR2 ( 50 ),
        executionTime int,
    method VARCHAR2 ( 200 ) 
    )

    (3)实体类

    package lucky.domain;
    
    import java.util.Date;
    
    /**
     * 系统日志实体类
     */
    public class SysLog {
    
        private String id;
        private Date visitTime;
        private String visitTimeStr;
        private String username;
        private String ip;
        private String url;
        private Long executionTime;
        private String method;
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        public Date getVisitTime() {
            return visitTime;
        }
    
        public void setVisitTime(Date visitTime) {
            this.visitTime = visitTime;
        }
    
        public String getVisitTimeStr() {
            return visitTimeStr;
        }
    
        public void setVisitTimeStr(String visitTimeStr) {
            this.visitTimeStr = visitTimeStr;
        }
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getIp() {
            return ip;
        }
    
        public void setIp(String ip) {
            this.ip = ip;
        }
    
        public String getUrl() {
            return url;
        }
    
        public void setUrl(String url) {
            this.url = url;
        }
    
        public Long getExecutionTime() {
            return executionTime;
        }
    
        public void setExecutionTime(Long executionTime) {
            this.executionTime = executionTime;
        }
    
        public String getMethod() {
            return method;
        }
    
        public void setMethod(String method) {
            this.method = method;
        }
    }

    2.AOP日志思路分析图

    3.代码部分

    (1)aop配置

    在springmvc.xml文件中添加如下内容:

    <!--
           支持AOP的注解支持,AOP底层使用代理技术
           JDK动态代理,要求必须有接口
           cglib代理,生成子类对象,proxy-target-class="true" 默认使用cglib的方式
       -->
        <aop:aspectj-autoproxy proxy-target-class="true"/>

    (2)AopLog.java(最重要)

    package lucky.controller;
    
    import lucky.domain.SysLog;
    import lucky.service.ISysLogService;
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.security.core.context.SecurityContext;
    import org.springframework.security.core.context.SecurityContextHolder;
    import org.springframework.security.core.userdetails.User;
    import org.springframework.stereotype.Component;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import javax.servlet.http.HttpServletRequest;
    import java.lang.reflect.Method;
    import java.util.Date;
    
    
    /**
     * AOP日志
     * 注意:获取url时,classAnnotation.path()还是classAnnotation.value()一定要和controller上的注解相一致,否则会报错
     * 可以打上断点看看
     */
    @Component
    @Aspect
    public class LogAop {
    
        @Autowired
        private HttpServletRequest request;
    
        @Autowired
        private ISysLogService sysLogService;
    
        private Date visitTime; //访问时间
        private Class clazz; //访问的类
        private Method method;//访问的方法
    
        /**
         * 前置通知,主要是获取开始时间,执行的类是哪一个,执行的是哪一个方法
         */
        @Before("execution(* lucky.controller.*.*(..))")
        public void doBefore(JoinPoint jp) throws Exception {
            visitTime = new Date();//当前时间就是开始访问的时间
            clazz = jp.getTarget().getClass(); //具体要访问的类
            String methodName = jp.getSignature().getName(); //获取访问的方法的名称
            Object[] args = jp.getArgs();//获取访问的方法的参数
    
            //获取具体执行的方法的Method对象
            if (args == null || args.length == 0) {
                method = clazz.getMethod(methodName); //只能获取无参数的方法
            } else {
                Class[] classArgs = new Class[args.length];
                for (int i = 0; i < args.length; i++) {
                    classArgs[i] = args[i].getClass();
                }
                clazz.getMethod(methodName, classArgs);
            }
        }
    
        /**
         * 后置通知
         */
        @After("execution(* lucky.controller.*.*(..))")
        public void doAfter(JoinPoint jp) throws Exception{
            long time = new Date().getTime() - visitTime.getTime(); //获取访问的时长
    
            String url = "";
            //获取url
            if (clazz != null && method != null && clazz != LogAop.class) {
                //1.获取类上的@RequestMapping("/orders")
                RequestMapping classAnnotation = (RequestMapping) clazz.getAnnotation(RequestMapping.class);
                //String[] classValue = classAnnotation.value();
                if (classAnnotation != null) {
                    String[] classValue = classAnnotation.path();
                    //2.获取方法上的@RequestMapping(xxx)
                    RequestMapping methodAnnotation = method.getAnnotation(RequestMapping.class);
                    if (methodAnnotation != null) {
                        String[] methodValue = methodAnnotation.path();
                        url = classValue[0] + methodValue[0];
    
                        //获取访问的ip
                        String ip = request.getRemoteAddr();
    
                        //利用springSecurity获取当前操作的用户
                        SecurityContext context = SecurityContextHolder.getContext();//从上下文中获了当前登录的用户
                        User user = (User) context.getAuthentication().getPrincipal();
                        String username = user.getUsername();
    
                        //将日志相关信息封装到SysLog对象
                        SysLog sysLog = new SysLog();
                        sysLog.setExecutionTime(time); //执行时长
                        sysLog.setIp(ip);
                        sysLog.setMethod("[类名] " + clazz.getName() + "[方法名] " + method.getName());
                        sysLog.setUrl(url);
                        sysLog.setUsername(username);
                        sysLog.setVisitTime(visitTime);
    
                        //调用Service完成操作
                        sysLogService.save(sysLog);
                    }
                }
            }
    
    
        }
    }

    (3)service层代码

    接口

    package lucky.service;
    
    import lucky.domain.SysLog;
    
    import java.util.List;
    
    public interface ISysLogService{
        void save(SysLog sysLog);
    
        List<SysLog> queryAll();
    }

    实现类

    package lucky.service.impl;
    
    import lucky.dao.ISysLogDao;
    import lucky.domain.SysLog;
    import lucky.service.ISysLogService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.util.List;
    
    @Service
    public class SysLogServiceImpl implements ISysLogService {
        @Autowired
        private ISysLogDao iSysLogDao;
    
        @Override
        public void save(SysLog sysLog) {
            iSysLogDao.save(sysLog);
        }
    
        @Override
        public List<SysLog> queryAll() {
            return iSysLogDao.queryAll();
        }
    }

    (5)持久层

    package lucky.dao;
    
    import lucky.domain.SysLog;
    import org.apache.ibatis.annotations.Select;
    
    import java.util.List;
    
    public interface ISysLogDao {
    
        @Select("insert into LUCKY.SYSLOG(visitTime,username,ip,url,executionTime,method) values(#{visitTime},#{username},#{ip},#{url},#{executionTime},#{method})")
        public void save(SysLog sysLog);
    
        @Select("select * from LUCKY.SYSLOG")
        List<SysLog> queryAll();
    }

    4.效果图

  • 相关阅读:
    安装lamp服务器
    Linux ssh登录命令
    一些替代Xshell的软件推荐
    字符串输入的几种方式
    Java数据库操作的一些注意
    模拟堆
    web安全基础第一天
    情报搜集
    kali中的postgres怎么连接
    LeetCode:Validate Binary Search Tree
  • 原文地址:https://www.cnblogs.com/luckyplj/p/11428777.html
Copyright © 2020-2023  润新知