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之類的代碼就不過多闡述了,比較簡單。。。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM