Struts2攔截器記錄系統操作日志


  • 前言

  最近開發了一個項目,由於項目在整個開發過程中處於趕時間狀態(每個項目都差不多如此)所以項目在收尾階段發現缺少記錄系統日志功能,以前系統都是直接寫在每個模塊的代碼中,然后存入表單,在頁面可以查看部分日志。這個系統並沒有此要求,因此便想到了做一個系統通用的日志記錄,主要記錄數據有:操作時間、操作對象、操作方法、操作的一些參數以及操作結果。剛開始直接想到的是利用aspect實現aop記錄日志,但實際應用中發現aspect並不能友好的攔截action,而是主要用作攔截service層業務。由於系統框架是基於ssh框架的,所以最終考慮使用struts2的自帶攔截器Interceptor。

  • 什么攔截器?

  攔截器是動態攔截Action調用的對象。它提供了一種機制可以使開發者可以定義在一個action執行的前后執行的代碼,也可以在一個action執行前阻止其執行。同時也是提供了一種可以提取action中可重用的部分的方式。談到攔截器,還有一個詞大家應該知道——攔截器鏈(Interceptor Chain,在Struts 2中稱為攔截器棧Interceptor Stack)。攔截器鏈就是將攔截器按一定的順序聯結成一條鏈。在訪問被攔截的方法或字段時,攔截器鏈中的攔截器就會按其之前定義的順序被調用。

  •  攔截器的原理和大致流程

 

   1.ActionInvocation初始化時,根據配置,加載Action相關的所有Interc eptor。

 

   2. 通過ActionInvocation.invoke方法調用Action實現時,執行Interceptor。

 

    Interceptor將很多功能從我們的Action中獨立出來,大量減少了我們Action的代碼,獨立出來的行為具有很好的重用性。XWork、WebWork的許多功能都是有Interceptor實現,可以在配置文件中組裝Action用到的Interceptor,它會按照你指定的順序,在Action執行前后運行。

  • 項目實現攔截器代碼
  1 package com.mnsn.utils;
  2 
  3 import java.io.BufferedWriter;
  4 import java.io.File;
  5 import java.io.FileWriter;
  6 import java.util.Calendar;
  7 import java.util.Map;
  8 import java.util.Set;
  9 
 10 import org.apache.struts2.ServletActionContext;
 11 
 12 import com.mnsn.project.user.User;
 13 import com.opensymphony.xwork2.ActionInvocation;
 14 import com.opensymphony.xwork2.interceptor.Interceptor;
 15 import com.opensymphony.xwork2.interceptor.PreResultListener;
 16 
 17 /**
 18  * 系統日志攔截器
 19  * @AUTHER LiuLonglong
 20  * @Motto Goals determine what you are going to be.
 21  * @URL http://www.cnblogs.com/mvilplss/
 22  * @Time 下午04:09:37
 23  * @Version
 24  */
 25 public class Dolog implements Interceptor {
 26 
 27     private static final long serialVersionUID = 1L;
 28 
 29     public String intercept(ActionInvocation ai) throws Exception {
 30 
 31         ai.addPreResultListener(new PreResultListener() {
 32 
 33             public void beforeResult(ActionInvocation ai, String arg1) {
 34                 try {
 35                     StringBuffer sb = new StringBuffer();
 36                     sb.append(MyUtils.getDataYmdhms2() + ":");
 37                     Map<String, Object> session = ai.getInvocationContext().getSession();
 38                     User user = (User) session.get("loginUser");
 39                     if (user != null) {
 40                         sb.append("操作人:" + user.getName());
 41                     } else {
 42                         sb.append("操作人:系統未獲取");
 43                     }
 44                     sb.append("類名:" + ai.getAction() + " ");
 45                     sb.append("方法名:" + ai.getInvocationContext().getName()+ " ");
 46                     Map<String, Object> map = ai.getInvocationContext().getParameters();
 47                     Set<String> keys = map.keySet();
 48                     sb.append("參數:");
 49                     for (String key : keys) {
 50                         sb.append(key + "=" + ((Object[]) map.get(key))[0]+ "#");
 51                     }
 52                     sb.append(" ");
 53                     sb.append("執行結果:" + ai.getResultCode() + " ");
 54                     String appPath = ServletActionContext.getServletContext().getRealPath("/");
 55                     saveLog(appPath + "operLog", sb.toString());
 56                 } catch (Exception e) {
 57                     e.printStackTrace();
 58                 }
 59 
 60             }
 61         });
 62 
 63         return ai.invoke();
 64     }
 65 
 66     public static void saveLog(String dir, String content) {
 67         try {
 68             File path = new File(dir);
 69             if (!path.exists()) {
 70                 path.mkdir();
 71             }
 72             File LogDir = new File(path + "/"
 73                     + (Calendar.getInstance().get(Calendar.MONTH) + 1));
 74             if (!LogDir.exists()) {
 75                 LogDir.mkdir();
 76             }
 77             File file = new File(LogDir + "/"
 78                     + Calendar.getInstance().get(Calendar.DAY_OF_MONTH)
 79                     + ".log");
 80             if (!file.exists()) {
 81                 file.createNewFile();
 82             }
 83             BufferedWriter br = new BufferedWriter(new FileWriter(file, true));
 84             br.write(content);
 85             br.newLine();
 86             br.flush();
 87             br.close();
 88 
 89             File LogDirOld = new File(
 90                     path
 91                             + "/"
 92                             + (Calendar.getInstance().get(Calendar.MONTH) - 2 > 0 ? (Calendar
 93                                     .getInstance().get(Calendar.MONTH) - 2)
 94                                     : Calendar.getInstance()
 95                                             .get(Calendar.MONTH) + 10));
 96             if (LogDirOld.exists()) {
 97                 File[] fileOlds = LogDirOld.listFiles();
 98                 for (File f : fileOlds) {
 99                     f.delete();
100                 }
101                 LogDirOld.delete();
102             }
103         } catch (Exception e) {
104             e.printStackTrace();
105         }
106 
107     }
108 
109     public void destroy() {
110 
111     }
112 
113     public void init() {
114 
115     }
116 }
  • 項目部分配置

 

<!-- 配置攔截器 -->
        <interceptors>
            <interceptor name="dolog" class="com.mnsn.utils.Dolog"></interceptor>
            <interceptor-stack name="defaultStack">
                <interceptor-ref name="dolog"></interceptor-ref>
                   <interceptor-ref name="defaultStack"></interceptor-ref>
               </interceptor-stack>
        </interceptors>

 

  • 執行結果

取自於文件:C:\Program Files (x86)\tomcat-6.0.43-myeclipse\webapps\qzdl\operLog\3\10.log

20150310173309:操作人:系統未獲取類名:com.mnsn.project.user.UserAction@b2c940 方法名:login 參數:loginname=ss#password=ss#x=31#y=11# 執行結果:pass 
20150310173313:操作人:欽州老大類名:com.mnsn.project.user.UserAction@1a2157e 方法名:list 參數: 執行結果:list 
20150310173322:操作人:欽州老大類名:com.mnsn.project.user.UserAction@108a2d1 方法名:delete 參數:users[0].id=402881ec4b38cf8f014b38d4510f0001# 執行結果:toList 
20150310173323:操作人:欽州老大類名:com.mnsn.project.user.UserAction@13e3101 方法名:list 參數: 執行結果:list 
20150310173326:操作人:欽州老大類名:com.mnsn.project.user.UserAction@158a9b 方法名:toOper 參數:user.id=402881fd4becf4d5014becf8253c0000# 執行結果:oper 
20150310173328:操作人:欽州老大類名:com.mnsn.project.user.UserAction@174edfd 方法名:update 參數:toWhere=#user.createtime=2015-03-06 10:44:20.0#user.group.id=402881ef4a9f4536014a9f69be6c0005#user.id=402881fd4becf4d5014becf8253c0000#user.job=部門主管#user.loginname=wml#user.mobilephone=18758010019#user.name=王明路#user.office_telephone=0571-6856156#user.password=123456#user.remark=此人為部門管理員#user.unit.id=402881fd4becf4d5014bed053ce80001# 執行結果:toList 
20150310173328:操作人:欽州老大類名:com.mnsn.project.user.UserAction@11efcc2 方法名:list 參數: 執行結果:list 
  • 總結

  struts2的攔截器相對aspect來說還是比較容易上手和理解的,對於要求一般的系統操作日志可以采用攔截器,而aspect重要用於細粒度的控制方法的出口和入口,實現邏輯層的增強,例如聲明式事物。

 

  • 備注

  本文在工作繁忙中碼出來的,如有錯誤在所難免,望讀者指出,謝謝!                    


免責聲明!

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



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