最近開發了一個項目,因爲項目在整個開發過程當中處於趕時間狀態(每一個項目都差很少如此)因此項目在收尾階段發現缺乏記錄系統日誌功能,之前系統都是直接寫在每一個模塊的代碼中,而後存入表單,在頁面能夠查看部分日誌。這個系統並無此要求,所以便想到了作一個系統通用的日誌記錄,主要記錄數據有:操做時間、操做對象、操做方法、操做的一些參數以及操做結果。剛開始直接想到的是利用aspect實現aop記錄日誌,但實際應用中發現aspect並不能友好的攔截action,而是主要用做攔截service層業務。因爲系統框架是基於ssh框架的,因此最終考慮使用struts2的自帶攔截器Interceptor。java
攔截器是動態攔截Action調用的對象。它提供了一種機制能夠使開發者能夠定義在一個action執行的先後執行的代碼,也能夠在一個action執行前阻止其執行。同時也是提供了一種能夠提取action中可重用的部分的方式。談到攔截器,還有一個詞你們應該知道——攔截器鏈(Interceptor Chain,在Struts 2中稱爲攔截器棧Interceptor Stack)。攔截器鏈就是將攔截器按必定的順序聯結成一條鏈。在訪問被攔截的方法或字段時,攔截器鏈中的攔截器就會按其以前定義的順序被調用。web
1.ActionInvocation初始化時,根據配置,加載Action相關的全部Interc eptor。apache
2. 經過ActionInvocation.invoke方法調用Action實現時,執行Interceptor。tomcat
Interceptor將不少功能從咱們的Action中獨立出來,大量減小了咱們Action的代碼,獨立出來的行爲具備很好的重用性。XWork、WebWork的許多功能都是有Interceptor實現,能夠在配置文件中組裝Action用到的Interceptor,它會按照你指定的順序,在Action執行先後運行。session
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.logapp
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重要用於細粒度的控制方法的出口和入口,實現邏輯層的加強,例如聲明式事物。框架
本文在工做繁忙中碼出來的,若有錯誤在所不免,望讀者指出,謝謝! eclipse