ssm框架中Aop关于日志管理的操作

对于日志的管理,我们要实现收集、存储和展示三个过程。(展示 ,我们就不过多介绍了,无非就是从数据库中调取日志并展示在页面上)

因为日志是要存储在数据库中的,所以我们先要弄清日志应该包含哪些内容,再创建一张数据表sysLog:

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)

)

定义一个实体类:

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() {
        if(visitTime!=null){
            visitTimeStr =  DateUtils.date2String(visitTime,"yyyy-MM-dd HH:mm");
        }
        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;
    }
}
View Code

基于AOP日志处理

创建切面类处理日志

@Component
@Aspect
public class LogAop {

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private ISysLogService sysLogService;

    private Date visitTime;//访问时间
    private Class clazz;//访问的类
    private Method method;//访问的方法
    //主要获取访问的时间、访问的类、访问的方法

    @Before("execution(* com.itheima.ssm.controller.*.*(..))")
    public void doBefore(JoinPoint jp) throws NoSuchMethodException,SecurityException{
        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(); //如果传递的方法参数类型为基本数据类型,一定要用它的包装类,如int 应改为Integer
            }
            method = clazz.getMethod(methodName,classArgs);
        }
    }

    //后置通知
    @After("execution(* com.itheima.ssm.controller.*.*(..))")
    public void doAfter(JoinPoint jp) throws Exception{
        long time = new Date().getTime() - visitTime.getTime();//获取访问的时长

        String url = "";

        if (clazz!=null&&method!=null&&clazz!=LogAop.class&&clazz!=SysLogController.class){
            //获取url
            //获取类上的@RequestMapping(value="/**")
            RequestMapping classAnnotation = (RequestMapping) clazz.getAnnotation(RequestMapping.class);
            if (classAnnotation!=null){
                String[] classValue = classAnnotation.value();
                //获取方法上的@RequestMapping(value="/**")
                RequestMapping methodAnnotation = method.getAnnotation(RequestMapping.class);
                if (methodAnnotation!=null){
                    String[] methodValue = methodAnnotation.value();
                    url = classValue[0]+methodValue[0];
                }
            }
            //获取访问的ip地址
            String ip= request.getRemoteAddr();

            //获取当前操作的用户
            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.setUsername(username);
            sysLog.setVisitTime(visitTime);
            sysLog.setUrl(url);

            //调用Service完成操作
            sysLogService.save(sysLog);

        }
    }

}
View Code

注意:在web.xml中,我们要定义一个request监听器:

<!-- 配置监听器 -->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
<!--定义一个request监听器--> <listener> <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> </listener>

在整合spring容器时使用ContextLoaderListener,它实现了ServletContextListener监听器接口,ServletContextListener

只负责监听web容器启动和关闭的事件.而RequestContextListener实现ServletRequestListener监听器接口,该监听器监听

HTTP请求事件,web服务器接收的每一次请求都会通知该监听器.

spring容器启动和关闭操作由web容器的启动和关闭事件触发,但如果spring容器中的Bean需要request,session,globalsession

作用域的支持,spring容器本身就必须获得web容器的HTTP请求事件,以HTTP请求的事件"驱动"Bean作用域的控制逻辑.

定义SysLogController

@Controller
@RequestMapping("/sysLog")
public class SysLogController {

    @Autowired
    private ISysLogService sysLogService;

    @RequestMapping("/findAll.do")
    public ModelAndView findAll() throws Exception{
        ModelAndView mv = new ModelAndView();
        List<SysLog> sysLogs = sysLogService.findAll();
        mv.addObject("sysLogs",sysLogs);
        mv.setViewName("syslog-list");
        return mv;
    }
}

其他相关的service、dao之类的代码就不过多阐述了,比较简单。。。

原文地址:https://www.cnblogs.com/churujianghudezai/p/12593614.html