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:操作人:系统未获取类名:[email protected] 方法名:login 参数:loginname=ss#password=ss#x=31#y=11# 执行结果:pass
20150310173313:操作人:钦州老大类名:[email protected] 方法名:list 参数: 执行结果:list
20150310173322:操作人:钦州老大类名:[email protected] 方法名:delete 参数:users[0].id=402881ec4b38cf8f014b38d4510f0001# 执行结果:toList
20150310173323:操作人:钦州老大类名:[email protected] 方法名:list 参数: 执行结果:list
20150310173326:操作人:钦州老大类名:[email protected] 方法名:toOper 参数:user.id=402881fd4becf4d5014becf8253c0000# 执行结果:oper
20150310173328:操作人:钦州老大类名:[email protected] 方法名: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:操作人:钦州老大类名:[email protected] 方法名:list 参数: 执行结果:list 
  • 总结

  struts2的拦截器相对aspect来说还是比较容易上手和理解的,对于要求一般的系统操作日志可以采用拦截器,而aspect重要用于细粒度的控制方法的出口和入口,实现逻辑层的增强,例如声明式事物。

  • 备注

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

时间: 2024-10-11 14:02:48

Struts2拦截器记录系统操作日志的相关文章

Struts2.x教程(三) Struts2拦截器

一.Struts2拦截器介绍 Struts2拦截器是使用AOP实现的,主要是针对action对象进行拦截,可以在访问action的某个方法.字段之前或之后实施拦截. 可以为action配置多个拦截器,Struts2会将这一组拦截器按照一定顺序组织成一个拦截器栈.action可以直接引用某个拦截器栈来实现配置多个拦截器的目的. 对于继承struts_default的package中的action,都会默认引用name=defaultStack的拦截器栈(在struts_default中定义了Str

Struts2 拦截器与Spring AOP的区别

在学习Spring AOP技术的同时,发现其实与以前做过的拦截器的功能很类似,于是开始抱着这两者之间有什么关系的问题进行深入研究. 我们知道struts2使用拦截器主要是用来处理用户的请求,OGNL的使用,表单验证 等. 而spring的拦截器,主要体现在AOP的事务管理方面,还有比如一些错误或者异常的日志的显示 也是通过配置spring的log拦截器来实现的. Struts的拦截器是针对Struts的,比如SSH项目都会去使用AOP ,如果是单纯的STRUTS项目 自然使用Struts本身的拦

【SSH2(实践篇)】--Struts2拦截器精解

上篇博客对Struts2的体系结构做了初步的了解,Struts2是以WebWork作为处理核心,并采用拦截器的机制来处理用户的请求,同时它还集成了Struts1丰富的标签库.另外上篇博客还对Struts2的配置使用进行了初步的介绍,下面将会集中讨论Struts2的拦截器. 一.拦截器 1.拦截器小介 拦截器的功能类似于web.xml文件中的Filter,能对用户的请求进行拦截,通过拦截用户的请求来实现对页面的控制.拦截器是在Struts-core-2.2.3.jar中进行配置的,原始的拦截器是在

Struts2拦截器的使用 (详解)

这位仁兄的写的不错,我照抄过来了:http://www.blogjava.net/i369/articles/162407.html 如何使用struts2拦截器,或者自定义拦截器.特别注意,在使用拦截器的时候,在Action里面必须最后一定要引用struts2自带的拦截器缺省堆栈defaultStack,如下(这里我是引用了struts2自带的checkbox拦截器):<interceptor-ref name="checkbox">  <param name=&q

Struts2拦截器详解

作者:禅楼望月 1. Struts2内置拦截器 Struts2内置了大量的拦截器,如下图: 图片来自:刘水镜的博客:菜鸟学SSH(四)--Struts2拦截器 这些拦截器以name-class的形式配置在struts-default.xml中: <interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/> <interceptor n

ssh2——struts2 拦截器

虽然没学过struts1吧,但是了解到struts1中并没有拦截器,  到Struts2才有,它是基于WebWork发展起来的, 顾名思义,说到拦截器大家首先肯定会想到它是拦截东西的,起到一个限制的作用,那么好,在这里它是拦截什么的呢?在struts2中拦截器是用来拦截Action的,在执行Action之前拦截器会起一定的作用,执行一些预先处理的代码, 接着去执行Action中相关的方法,之后,又会回到拦截器里面,接着去执行后续的一些操作.刚刚学习,如果我理解的不对的话,请大家留言指正啊. St

基于SSH2框架Struts2拦截器的登录验证实现(转)

大象在这里假设你已经弄清楚了Struts2拦截器的基本概念,可以进入实际运用了.那么我们在之前的基础上只需要做下小小的改变,就可以使用Struts2的拦截器机制实现登录的验证. 修改数据库 在user表中增加password字段,将初始密码都设为123,因为是示例所以采用明码,实际开发中,当然不能这样做,需要进行加密处理.再将name改为username,其实name字段可以不用改名,我这样做是为了命名规范,请注意,如果字段改为username,User类中的对应属性也要进行相应变化(如果你加注

深入分析JavaWeb 47 -- Struts2拦截器与文件上传下载

一.struts2中的拦截器(框架功能核心) 1.过滤器VS拦截器 过滤器VS拦截器功能是一回事.过滤器是Servlet规范中的技术,可以对请求和响应进行过滤. 拦截器是Struts2框架中的技术,实现AOP(面向切面)的编程思想,是可插拔的, 可以对访问某个 Action 方法之前或之后实施拦截. 拦截器栈(Interceptor Stack): 将拦截器按一定的顺序联结成一条链. 在访问被拦截的方法时, Struts2拦截器链中的拦截器就会按其之前定义的顺序被依次调用 Struts2执行原理

深入分析JavaWeb Item47 -- Struts2拦截器与文件上传下载

一.struts2中的拦截器(框架功能核心) 1.过滤器VS拦截器 过滤器VS拦截器功能是一回事. 过滤器是Servlet规范中的技术,能够对请求和响应进行过滤. 拦截器是Struts2框架中的技术.实现AOP(面向切面)的编程思想.是可插拔的, 能够对訪问某个 Action 方法之前或之后实施拦截. 拦截器栈(Interceptor Stack): 将拦截器按一定的顺序联结成一条链. 在訪问被拦截的方法时, Struts2拦截器链中的拦截器就会按其之前定义的顺序被依次调用 Struts2运行原