zoukankan      html  css  js  c++  java
  • 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重要用于细粒度的控制方法的出口和入口,实现逻辑层的增强,例如声明式事物。

    • 备注

      本文在工作繁忙中码出来的,如有错误在所难免,望读者指出,谢谢!                    

  • 相关阅读:
    WPF框架MVVM简单例子
    向WPF的Grid里面增加控件
    静态资源(StaticResource)和动态资源(DynamicResource)
    WPF中INotifyPropertyChanged用法与数据绑定
    wpf 绑定数据无法更新ui控件可能存在的问题
    C#调用Resources.resx资源文件中的资源
    C# 委托的理解
    Codeforces 524E Rooks and Rectangles 线段树
    Codeforces 1000F One Occurrence 主席树|| 离线+线段树
    GYM 101673 A
  • 原文地址:https://www.cnblogs.com/mvilplss/p/4326626.html
Copyright © 2011-2022 走看看