论坛首页 Java企业应用论坛

使用Struts2拦截器实现日志管理系统

浏览 12154 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (1) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-02-26   最后修改:2009-02-26
   最近一个项目客户要求能够监控用户对系统的详细操作步骤,比如某人在某时间删除了某个模块的某条数据,经过一番斟酌,决定用struts2的拦截器功能实现日志管理系统,因为系统是旧系统(SSH架构)了,用struts2就可以不用修改系统的原有的类或者方法,而且可以精确到用户的具体操作,并且所有的日志管理代码直接写在拦截器里即可。代码如下:
  
@SuppressWarnings("serial")
public class LogInterceptor extends AbstractInterceptor{
	private String logName;
	private String logContent;
	protected Logger log = Logger.getLogger(getClass());
	
	public void init() {
    }

	@Override
    public String intercept(ActionInvocation ai) throws Exception  {
       Map session = ai.getInvocationContext().getSession();
       Object action = ai.getAction();
       String method = ai.getProxy().getMethod();
       try{
	       if(StringUtils.isBlank(method)) method = "method";
	       SysUser sysUser = (SysUser)session.get(Constants.SESSION_USER_KEY);
	       String userName = "";
	       if(sysUser!=null) userName = sysUser.getUserName();
	       String currentTime = TimeHelper.getCurrentTime();
	       String logContentHead = "用户"+userName+currentTime;
	       ai.invoke();//执行被拦截action
	       
	       if (action instanceof SysOrgAction) {
	    	   if(method.equals("save")){
		    	   logName = "保存部门";
		    	   logContent = logContentHead +"保存部门:"+ai.getStack().findValue("sysOrg.orgName");
		    	   log.info(logContent);
		    	   addSysLog(logName,logContent);
	    	   }
	    	   if(method.equals("delete")){
		    	   logName = "删除部门";
		    	   logContent = logContentHead +"删除"+((String[])(ai.getStack().findValue("flag_id"))).length+"条部门信息";
		    	   log.info(logContent);
		    	   addSysLog(logName,logContent);
	    	   }
	       }
	       if (action instanceof SysOrgForAdmAction) {
	    	   if(method.equals("save")){
		    	   logName = "保存单位";
		    	   logContent = logContentHead +"保存单位:"+ai.getStack().findValue("sysOrg.orgName");
		    	   log.info(logContent);
		    	   addSysLog(logName,logContent);
	    	   }
	    	   if(method.equals("delete")){
		    	   logName = "删除单位";
		    	   logContent = logContentHead +"删除1条单位信息";
		    	   log.info(logContent);
		    	   addSysLog(logName,logContent);
	    	   }
	       }
	       if (action instanceof SysUserAction || action instanceof SysUserForAdmAction) {
	    	   if(method.equals("save")){
		    	   logName = "保存用户";
		    	   logContent = logContentHead +"保存用户:"+ai.getStack().findValue("sysUser.userName");
		    	   log.info(logContent);
		    	   addSysLog(logName,logContent);
	    	   }
	    	   if(method.equals("delete")){
		    	   logName = "删除用户";
		    	   logContent = logContentHead +"删除"+((String[])(ai.getStack().findValue("flag_id"))).length+"条用户信息";
		    	   log.info(logContent);
		    	   addSysLog(logName,logContent);
	    	   }
	       }
	       
       }catch(Exception e){
    	   e.printStackTrace();
       }
       return Action.SUCCESS;
   } 
   
	/**
	 * 插入系统日志
	 * @param logName
	 * @param logContent
	 */
   private void addSysLog(String logName,String logContent){
	   HttpServletRequest request = ServletActionContext.getRequest();
	   SysLogService sysLogService = (SysLogService)ApplicationContextFactory.getApplicationContext().getBean("sysLogService");
	   SysLog sysLog = new SysLog();
	   sysLog.setLogName(logName);
	   sysLog.setLogContent(logContent);
	   sysLog.setLogType(Constants.LOG_TYPE_SYS);
	   sysLog.setLogTime(TimeHelper.getCurrentTime());
	   sysLog.setLogIp(request.getRemoteAddr());
	   sysLog.setLogKey(logName);
	   sysLogService.saveLog(sysLog);
   }
}
   发表时间:2009-02-26  
那要是系统中的 Action 非常多的话,岂不是要这样一直if下去?
1 请登录后投票
   发表时间:2009-02-26  
igogo007 写道
那要是系统中的 Action 非常多的话,岂不是要这样一直if下去?

代码只是当时写的一个简单测试例子,可以进行优化,将各个acton及对应的方法及操作等都可以进行配置,如配置到一个xml文件当中,以后系统中新增加了action去修改xml文件就可以了。这样就不用去写大量的if,也不用每次有新增action来改日志管理系统的代码了。
1 请登录后投票
   发表时间:2009-02-26  
跟我的做法差不多,不过我是用数据库存了url及template等.
用拦截到的url来获取对应的template, 该template是一个ONGL表达式,然后解析该表达式,入库。

还是一点差别是不是在ai.invoke();后记log,而是在拦截方法里面用
invocation.addPreResultListener(new PreResultListener(){
  public void beforeResult(ActionInvocation invocation, String resultCode) {
    ValueStack vs = getValueStack();
    vs.set(LogProcessor.RESULTCODE,resultCode);
    getLogProcessor().log(vs);
  }
}
1 请登录后投票
   发表时间:2009-02-26  
楼上采用了addPreResultListener方法也不错,封装的比较好~
0 请登录后投票
   发表时间:2009-05-12  
管理操作如果回滚怎么办?
应该在service层来加aop统一管理
0 请登录后投票
   发表时间:2009-05-12  
freedxz 写道
管理操作如果回滚怎么办?
应该在service层来加aop统一管理

说的好。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics