zoukankan      html  css  js  c++  java
  • SSM14-通过AOP实现日志记录

    1.要求使用AOP思想,实现对每一个用户登陆后,将以下信息保存在数据库

      1>登陆时间

      2>退出时间

      3>登录的IP地址

      4>访问点URL(访问了那些Controller)

           5>访问总时间

    2.实体类存放需要的信息

    @Data
    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;
    }

    3.通过前置通知和后置通知实现该功能

    @Component
    @Aspect
    public class LogAop {
    
        @Autowired
        private HttpServletRequest request;
        @Autowired
        private ISysLogService sysLogService;
        private Date startTime; // 访问时间
        private Class executionClass;// 访问的类
        private Method executionMethod; // 访问的方法
    
        // 主要获取访问时间、访问的类、访问的方法
        @Before("execution(* com.hdh.web.controller.*.*(..))")
        public void doBefore(JoinPoint jp) throws NoSuchMethodException, SecurityException {
            System.out.println("=============================================");
    
            startTime = new Date(); // 访问时间
            // 获取访问的类
            executionClass = jp.getTarget().getClass();
            // 获取访问的方法
            String methodName = jp.getSignature().getName();// 获取访问的方法的名称
            Object[] args = jp.getArgs();// 获取访问的方法的参数
            if (args == null || args.length == 0) {// 无参数
                executionMethod = executionClass.getMethod(methodName); // 只能获取无参数方法
            } else {
                // 有参数,就将args中所有元素遍历,获取对应的Class,装入到一个Class[]
                Class[] classArgs = new Class[args.length];
                for (int i = 0; i < args.length; i++) {
                    classArgs[i] = args[i].getClass();
                }
                executionMethod = executionClass.getMethod(methodName, classArgs);// 获取有参数方法
                System.out.println(executionMethod);
            }
        }
    
        // 主要获取日志中其它信息,时长、ip、url...
        @After("execution(* com.hdh.web.controller.*.*(..))")
        public void doAfter(JoinPoint jp) throws Exception {
            // 获取类上的@RequestMapping对象
            if (executionClass != SysLogController.class) {
                RequestMapping classAnnotation = (RequestMapping) executionClass.getAnnotation(RequestMapping.class);
                if (classAnnotation != null) {
                    // 获取方法上的@RequestMapping对象
                    RequestMapping methodAnnotation = executionMethod.getAnnotation(RequestMapping.class);
                    if (methodAnnotation != null) {
                        String url = ""; // 它的值应该是类上的@RequestMapping的value+方法上的@RequestMapping的value
                        url = classAnnotation.value()[0] + methodAnnotation.value()[0];
                        SysLog sysLog = new SysLog();
                        // 获取访问时长
                        Long executionTime = new Date().getTime() - startTime.getTime();
                        // 将sysLog对象属性封装
                        sysLog.setExecutionTime(executionTime);
                        sysLog.setUrl(url);
                        // 获取ip
                        String ip = request.getRemoteAddr();
                        sysLog.setIp(ip);
                        // 可以通过securityContext获取,也可以从request.getSession中获取
                        // SecurityContext context = SecurityContextHolder.getContext(); //request.getSession().getAttribute("SPRING_SECURITY_CONTEXT")
                        //String username = ((Employee) (context.getAuthentication().getPrincipal())).getUsername();
                        String username = (String) request.getSession().getAttribute("username");
                        sysLog.setUsername(username);
                        sysLog.setMethod("[类名]" + executionClass.getName() + "[方法名]" +
                                executionMethod.getName());
                        sysLog.setVisitTime(startTime);
                        // 调用Service,调用dao将sysLog insert数据库
                        sysLogService.save(sysLog);
                    }
                }
            }
        }
    }

     4.支持AOP的注解支持,AOP底层使用代理技术

    JDK动态代理,要求必须有接口
    cglib代理,生成子类对象,proxy-target-class="true" 默认使用cglib的方式

    在springmvc中加上:

    <aop:aspectj-autoproxy proxy-target-class="true"/>
  • 相关阅读:
    shell
    Python全栈开发:django网络框架(二)
    Python全栈开发:django网络框架(一)
    动态规划问题以及诸多实例分析
    python实现并查集
    使用命令行编译和运行 c、Java和python程序
    整数除法操作的取整问题
    使用TensorFlow低级别的API进行编程
    使用TensorFlow高级别的API进行编程
    TensorFlow安装和HelloWorld
  • 原文地址:https://www.cnblogs.com/asndxj/p/11844332.html
Copyright © 2011-2022 走看看