zoukankan      html  css  js  c++  java
  • 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.效果图

  • 相关阅读:
    Java程序:从命令行接收多个数字,求和并输出结果
    大道至简读后感
    大道至简第一章读后感Java伪代码
    Creating a SharePoint BCS .NET Connectivity Assembly to Crawl RSS Data in Visual Studio 2010
    声明式验证超时问题
    Error message when you try to modify or to delete an alternate access mapping in Windows SharePoint Services 3.0: "An update conflict has occurred, and you must re-try this action"
    Upgrading or Redeploying SharePoint 2010 Workflows
    Upgrade custom workflow in SharePoint
    SharePoint 2013中Office Web Apps的一次排错
    How to upgrade workflow assembly in MOSS 2007
  • 原文地址:https://www.cnblogs.com/luckyplj/p/11428777.html
Copyright © 2011-2022 走看看