log4j记录系统中的日志信息,主要是异常信息!或者是用户自定义的信息,便于用户或者程序员,发现错误信息及时调整、修改bug.
对于用户登陆系统后,它所进行的操作我们有时后也需要进行记录。这个就要使用操作日志了,自己动手写吧!我这个利用Spring的Aop实现的!我是在bizImpl对业务时行处理,主要功能也是集中在这一块。所以切的时候也是切在这一块。Action层中只负责调用bizImpl层的方法。切面类也是一个普通的java类,它里面有个logging当它捕获它bizImpl中的方法时,就会进入到这个方法中。我们可以得到拦截方法的名字以及方法中的参数信息,其后可以将操作信息加入到数据库中进行保存。

/** 

 * Copyright(C): iusesoft 

 * author: author 

 * comments: 切面类,对拦截的方法进行判断 

 * version: 1.00 

 * date: Jul 31, 2010 

 */ 

package com.iusersoft.util; 


import java.text.SimpleDateFormat; 

import java.util.Date; 


import org.aspectj.lang.JoinPoint; 


import com.iusersoft.system.biz.impl.OperateLogBizImp; 

import com.iusersoft.system.entity.OperateLog; 


public class OperatorAspect{ 

 /*private OperatorLogAction operatorLog; 


 public OperatorLogAction getOperatorLog() { 

 return operatorLog; 

 } 


 public void setOperatorLog(OperatorLogAction operatorLog) { 

 this.operatorLog = operatorLog; 

 }*/ 


 private OperateLogBizImp operateLogBiz; 


 public OperateLogBizImp getOperateLogBiz() { 

 return operateLogBiz; 

 } 


 public void setOperateLogBiz(OperateLogBizImp operateLogBiz) { 

 this.operateLogBiz = operateLogBiz; 

 } 


 /** 

 * 定义advice,即切面类中方法具体实现, 这里主要是用于记录日志,只做简单处理。 

 * 

 * @param joinPoint,可以取得被拦截方法的一些信息 

 */ 

 public void logging(JoinPoint joinPoint) { 

 [color=red]//得到被拦截方法参数,并打印[/color] 

 /*Object[] args = joinPoint.getArgs(); 

 for (int i = 0; i < args.length; i++) { 

 System.out.println("method arg 拦截到的参数名:" + i + " -- " + args[i]); 

 }*/ 

[color=red]//拦截到方法的名称[/color] 

 String actionName = joinPoint.getSignature().getName(); 

 //操作类型名称 

 String actionType = ArgObject.OperatorActionName(actionName); 

 //操作的表名 

 String operateName=ArgObject.argObjecgt(actionName)+"表进行的"+actionType; 


 if("无匹配表进行的没有匹配的方法名".equals(operateName)){ 

 operateName=actionName; 

 } 

 //考虑到效率对于查询没有进行保存 

 if(!("查询".equals(actionType))) 

 { 

 OperateLog log = new OperateLog(); 

 try{ 

 log.setOperate(actionType); 

 log.setOperateCode(24); 

 log.setOperateLogId(963); 

 log.setOperateName("hh"); 

 log.setOperateTime(new Date()); 

 log.setOperateObject(operateName); 

 operateLogBiz.addLog(log); 

 }catch(Exception ex){ 

 ex.printStackTrace(); 

 } 

 }else{ 

 //可以方便地修改日期格式 

 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM hh:mm:ss"); 

 String targetDate = dateFormat.format( new Date() ); 

 System.out.println(targetDate+ operateName); 

 } 

 } 

} 


先看看applicationContext.xml的配置信息: 


<!-- 配置aspect切面类 --> 

 <bean id="operatorAspect" class="com.iusersoft.util.OperatorAspect" > 

<!--操作日志中注入的operateLogBiz--> 

 <property name="operateLogBiz" ref="operatorLogBiz2"></property> 

 </bean> 

 <!-- 配置AOP --> 

 <aop:config> 

 <!-- 配置aspect切面类 --> 

 <aop:aspect ref="operatorAspect"> 

 [color=red]<!-- 配置pointcut,即切入点,对哪些类的哪些方法起到AOP的作用 -->[/color] 

<aop:pointcut id="userServiceMethods" 

 expression="execution(* com.iusersoft.*.biz.impl.*Impl.*(..))" /> 

[color=red] <!-- 配置advice,即Aspect类中的logging()方法,这里采用在业务方法执行前进行拦截 -->[/color] 

 <aop:before method="logging" pointcut-ref="userServiceMethods" /> 

 </aop:aspect> 

 </aop:config> 


日志操作的Action 

/** 

 * Copyright(C): iusesoft 

 * author: user1 

 * comments: 日志操作 

 * version: 1.00 

 * date: Aug 2, 2010 

 */ 

package com.iusersoft.system.action; 


import com.iusersoft.base.BaseAction; 

import com.iusersoft.system.biz.IOperateLogBiz; 


public class OperatorLogAction extends BaseAction { 


 private IOperateLogBiz operateLogBiz; 


 public IOperateLogBiz getOperateLogBiz() { 

 return operateLogBiz; 

 } 


 public void setOperateLogBiz(IOperateLogBiz operateLogBiz) { 

 this.operateLogBiz = operateLogBiz; 

 } 


 private int start; 

 public int getStart() { 

 return start; 

 } 


 public void setStart(int start) { 

 this.start = start; 

 } 


 private int limit; 

 public int getLimit() { 

 return limit; 

 } 


 public void setLimit(int limit) { 

 this.limit = limit; 

 } 



 /********* 

 * 查询所有日志信息 

 * @return 

 */ 

 public String selectAlloperatorLog(){ 

 try{ 

 operateLogBiz.selectAllOperatorLog(start, limit, response); 

 }catch(Exception ex){ 

 ex.printStackTrace(); 

 } 

 return null; 

 } 

 /******** 

 * 删除日志信息 

 * @return 

 */ 

 public String deleteAllOperatorLog(){ 

 try{ 

 operateLogBiz.deleteAllOperatorLog(); 

 }catch(Exception ex){ 

 ex.printStackTrace(); 

 } 

 return null; 

 } 


 //查询功能用到的变量 

 private String condition ; 


 public String getCondition() { 

 return condition; 

} 


public void setCondition(String condition) { 

 this.condition = condition; 

} 

/********* 

 * 查询日志功能 

 * @condition 查询条件 

 * @start 显示记录的开始位置 

 * @limit 每页显示的记录条数 

 * @response 客户端写数据的对象 

 */ 

public String queryOperatorLog(){ 

 try{ 

 operateLogBiz.queryOperatorLog(condition, start, limit, response); 

 }catch(Exception ex){ 

 ex.printStackTrace(); 

 } 

 return null; 

 } 





} 


日志操作的bizImpl层 

/** 

 * Copyright(C): iusesoft 

 * author: author 

 * comments: 日志操作的bizImple 

 * version: 1.00 

 * date: Aug 2, 2010 

 */ 

package com.iusersoft.system.biz.impl; 


import java.text.ParseException; 

import java.util.List; 


import javax.servlet.http.HttpServletResponse; 


import org.apache.log4j.Logger; 


import com.iusersoft.system.biz.IOperateLogBiz; 

import com.iusersoft.system.dao.IOperateLogDao; 

import com.iusersoft.system.entity.OperateLog; 

import com.iusersoft.util.OperatorDate; 

import com.iusersoft.util.PageUtil; 


public class OperateLogBizImp implements IOperateLogBiz { 



 //日志记录器 

 public static Logger logger = Logger.getLogger(OperateLogBizImp.class); 

 private IOperateLogDao operateLogDao; 


 public IOperateLogDao getOperateLogDao() { 

 return operateLogDao; 

 } 

 public void setOperateLogDao(IOperateLogDao operateLogDao) { 

 this.operateLogDao = operateLogDao; 

 } 

/********* 

 * 实现对日志的保存功能 

 * @log 要保存的日志对象 

 */ 

 public void addLog(OperateLog log) { 

 try{ 

 operateLogDao.add(log); 

 }catch(Exception ex){ 

 ex.printStackTrace(); 

 logger.error("出错了!",ex); 

 } 

 } 

 /****** 

 * 返回数据库中操作日志的个数 

 */ 

 public int queryOperatorLogCount(){ 

 String hql="from OperateLog"; 

 return operateLogDao.queryByHQL(hql).size(); 

 } 

 /******* 

 * 查询操作日志信息 

 * @start 显示记录开始位置 

 * @limit 每页显示的记录条数 

 * @response 客户端写数据的对象 

 */ 

 public void selectAllOperatorLog(int start,int limit,HttpServletResponse response) { 

 String hql ="from OperateLog"; 

 List<OperateLog> listOperateLog; 

 try{ 

 //先删除,在查询 

 this.deleteDateOperatorLog(); 

 listOperateLog = operateLogDao.queryByHQLForPagination(hql, start, limit); 

 int totalProperty = this.queryOperatorLogCount(); 

 PageUtil.pageSet(totalProperty,listOperateLog, response); 

 }catch(Exception ex){ 

 ex.printStackTrace(); 

 logger.error("出错了!",ex); 

 } 

 } 

/******* 

 * 删除日志数据中的记录 

 */ 

 public void deleteAllOperatorLog() { 

 String hql="delete from i_xt_operatelog where 1=1"; 

 try{ 

 //System.out.println(""); 

 operateLogDao.deleteAll(hql); 

 //System.out.println(hql); 

 }catch(Exception ex){ 

 ex.printStackTrace(); 

 logger.error("出错了!",ex); 

 } 

 } 


/******* 

 * 删除本月以外的日志信息 

 * @throws ParseException 

 */ 

 public void deleteDateOperatorLog() throws ParseException { 

 //先得到日 

 String today = OperatorDate.operatorLogDay(); 

 String sql=""; 

 if("01".equals(today)){ 

 //得到当前月份 

 String targetDate =OperatorDate.operatorLogDate(); 

 sql = "delete from i_xt_operatelog where operateTime < "+"'"+targetDate+"'"; 

 try{ 

 operateLogDao.deleteAll(sql); 

 }catch (Exception ex) { 

 ex.printStackTrace(); 

 logger.error("出错了!",ex); 

 } 

 } 

 // System.out.println("sql:"+sql); 

 } 



 /********** 

 * @condition 查询条件 

 * @start 显示记录的开始位置 

 * @limit 每页显示的记录条数 

 * @response 客户端写数据的对象 

 */ 

 public void queryOperatorLog(String condition, int start, int limit, 

 HttpServletResponse response) { 

 String hql="from OperateLog log"; 

 boolean flag = false; 

 if(null==condition || condition.equals("输入查询条件")){ 

 hql="from OperateLog log"; 

 }else{ 

 flag = true; 

 hql +=" where log.operateName='"+condition+"'"; 

 } 

 //System.out.println(hql); 

 List<OperateLog> listOperateLog ; 

 int totalProperty=0; 

 try{ 

 listOperateLog = operateLogDao.queryByHQLForPagination(hql, start, limit); 

 if(!flag){ 

 totalProperty = this.queryOperatorLogCount(); 

 }else{ 

 totalProperty =listOperateLog.size(); 

 } 

 PageUtil.pageSet(totalProperty, listOperateLog, response); 

 }catch(Exception ex){ 

 ex.printStackTrace(); 

 logger.error("出错了!",ex); 

 } 

} 


}
/** 

 * Copyright(C): iusesoft 

 * author: author 

 * comments: 切面类,对拦截的方法进行判断 

 * version: 1.00 

 * date: Jul 31, 2010 

 */ 

package com.iusersoft.util; 


import java.text.SimpleDateFormat; 

import java.util.Date; 


import org.aspectj.lang.JoinPoint; 


import com.iusersoft.system.biz.impl.OperateLogBizImp; 

import com.iusersoft.system.entity.OperateLog; 


public class OperatorAspect{ 

 /*private OperatorLogAction operatorLog; 


 public OperatorLogAction getOperatorLog() { 

 return operatorLog; 

 } 


 public void setOperatorLog(OperatorLogAction operatorLog) { 

 this.operatorLog = operatorLog; 

 }*/ 


 private OperateLogBizImp operateLogBiz; 


 public OperateLogBizImp getOperateLogBiz() { 

 return operateLogBiz; 

 } 


 public void setOperateLogBiz(OperateLogBizImp operateLogBiz) { 

 this.operateLogBiz = operateLogBiz; 

 } 


 /** 

 * 定义advice,即切面类中方法具体实现, 这里主要是用于记录日志,只做简单处理。 

 * 

 * @param joinPoint,可以取得被拦截方法的一些信息 

 */ 

 public void logging(JoinPoint joinPoint) { 

 [color=red]//得到被拦截方法参数,并打印[/color] 

 /*Object[] args = joinPoint.getArgs(); 

 for (int i = 0; i < args.length; i++) { 

 System.out.println("method arg 拦截到的参数名:" + i + " -- " + args[i]); 

 }*/ 

[color=red]//拦截到方法的名称[/color] 

 String actionName = joinPoint.getSignature().getName(); 

 //操作类型名称 

 String actionType = ArgObject.OperatorActionName(actionName); 

 //操作的表名 

 String operateName=ArgObject.argObjecgt(actionName)+"表进行的"+actionType; 


 if("无匹配表进行的没有匹配的方法名".equals(operateName)){ 

 operateName=actionName; 

 } 

 //考虑到效率对于查询没有进行保存 

 if(!("查询".equals(actionType))) 

 { 

 OperateLog log = new OperateLog(); 

 try{ 

 log.setOperate(actionType); 

 log.setOperateCode(24); 

 log.setOperateLogId(963); 

 log.setOperateName("hh"); 

 log.setOperateTime(new Date()); 

 log.setOperateObject(operateName); 

 operateLogBiz.addLog(log); 

 }catch(Exception ex){ 

 ex.printStackTrace(); 

 } 

 }else{ 

 //可以方便地修改日期格式 

 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM hh:mm:ss"); 

 String targetDate = dateFormat.format( new Date() ); 

 System.out.println(targetDate+ operateName); 

 } 

 } 

} 


先看看applicationContext.xml的配置信息: 


<!-- 配置aspect切面类 --> 

 <bean id="operatorAspect" class="com.iusersoft.util.OperatorAspect" > 

<!--操作日志中注入的operateLogBiz--> 

 <property name="operateLogBiz" ref="operatorLogBiz2"></property> 

 </bean> 

 <!-- 配置AOP --> 

 <aop:config> 

 <!-- 配置aspect切面类 --> 

 <aop:aspect ref="operatorAspect"> 

 [color=red]<!-- 配置pointcut,即切入点,对哪些类的哪些方法起到AOP的作用 -->[/color] 

<aop:pointcut id="userServiceMethods" 

 expression="execution(* com.iusersoft.*.biz.impl.*Impl.*(..))" /> 

[color=red] <!-- 配置advice,即Aspect类中的logging()方法,这里采用在业务方法执行前进行拦截 -->[/color] 

 <aop:before method="logging" pointcut-ref="userServiceMethods" /> 

 </aop:aspect> 

 </aop:config> 


日志操作的Action 

/** 

 * Copyright(C): iusesoft 

 * author: user1 

 * comments: 日志操作 

 * version: 1.00 

 * date: Aug 2, 2010 

 */ 

package com.iusersoft.system.action; 


import com.iusersoft.base.BaseAction; 

import com.iusersoft.system.biz.IOperateLogBiz; 


public class OperatorLogAction extends BaseAction { 


 private IOperateLogBiz operateLogBiz; 


 public IOperateLogBiz getOperateLogBiz() { 

 return operateLogBiz; 

 } 


 public void setOperateLogBiz(IOperateLogBiz operateLogBiz) { 

 this.operateLogBiz = operateLogBiz; 

 } 


 private int start; 

 public int getStart() { 

 return start; 

 } 


 public void setStart(int start) { 

 this.start = start; 

 } 


 private int limit; 

 public int getLimit() { 

 return limit; 

 } 


 public void setLimit(int limit) { 

 this.limit = limit; 

 } 



 /********* 

 * 查询所有日志信息 

 * @return 

 */ 

 public String selectAlloperatorLog(){ 

 try{ 

 operateLogBiz.selectAllOperatorLog(start, limit, response); 

 }catch(Exception ex){ 

 ex.printStackTrace(); 

 } 

 return null; 

 } 

 /******** 

 * 删除日志信息 

 * @return 

 */ 

 public String deleteAllOperatorLog(){ 

 try{ 

 operateLogBiz.deleteAllOperatorLog(); 

 }catch(Exception ex){ 

 ex.printStackTrace(); 

 } 

 return null; 

 } 


 //查询功能用到的变量 

 private String condition ; 


 public String getCondition() { 

 return condition; 

} 


public void setCondition(String condition) { 

 this.condition = condition; 

} 

/********* 

 * 查询日志功能 

 * @condition 查询条件 

 * @start 显示记录的开始位置 

 * @limit 每页显示的记录条数 

 * @response 客户端写数据的对象 

 */ 

public String queryOperatorLog(){ 

 try{ 

 operateLogBiz.queryOperatorLog(condition, start, limit, response); 

 }catch(Exception ex){ 

 ex.printStackTrace(); 

 } 

 return null; 

 } 





} 


日志操作的bizImpl层 

/** 

 * Copyright(C): iusesoft 

 * author: author 

 * comments: 日志操作的bizImple 

 * version: 1.00 

 * date: Aug 2, 2010 

 */ 

package com.iusersoft.system.biz.impl; 


import java.text.ParseException; 

import java.util.List; 


import javax.servlet.http.HttpServletResponse; 


import org.apache.log4j.Logger; 


import com.iusersoft.system.biz.IOperateLogBiz; 

import com.iusersoft.system.dao.IOperateLogDao; 

import com.iusersoft.system.entity.OperateLog; 

import com.iusersoft.util.OperatorDate; 

import com.iusersoft.util.PageUtil; 


public class OperateLogBizImp implements IOperateLogBiz { 



 //日志记录器 

 public static Logger logger = Logger.getLogger(OperateLogBizImp.class); 

 private IOperateLogDao operateLogDao; 


 public IOperateLogDao getOperateLogDao() { 

 return operateLogDao; 

 } 

 public void setOperateLogDao(IOperateLogDao operateLogDao) { 

 this.operateLogDao = operateLogDao; 

 } 

/********* 

 * 实现对日志的保存功能 

 * @log 要保存的日志对象 

 */ 

 public void addLog(OperateLog log) { 

 try{ 

 operateLogDao.add(log); 

 }catch(Exception ex){ 

 ex.printStackTrace(); 

 logger.error("出错了!",ex); 

 } 

 } 

 /****** 

 * 返回数据库中操作日志的个数 

 */ 

 public int queryOperatorLogCount(){ 

 String hql="from OperateLog"; 

 return operateLogDao.queryByHQL(hql).size(); 

 } 

 /******* 

 * 查询操作日志信息 

 * @start 显示记录开始位置 

 * @limit 每页显示的记录条数 

 * @response 客户端写数据的对象 

 */ 

 public void selectAllOperatorLog(int start,int limit,HttpServletResponse response) { 

 String hql ="from OperateLog"; 

 List<OperateLog> listOperateLog; 

 try{ 

 //先删除,在查询 

 this.deleteDateOperatorLog(); 

 listOperateLog = operateLogDao.queryByHQLForPagination(hql, start, limit); 

 int totalProperty = this.queryOperatorLogCount(); 

 PageUtil.pageSet(totalProperty,listOperateLog, response); 

 }catch(Exception ex){ 

 ex.printStackTrace(); 

 logger.error("出错了!",ex); 

 } 

 } 

/******* 

 * 删除日志数据中的记录 

 */ 

 public void deleteAllOperatorLog() { 

 String hql="delete from i_xt_operatelog where 1=1"; 

 try{ 

 //System.out.println(""); 

 operateLogDao.deleteAll(hql); 

 //System.out.println(hql); 

 }catch(Exception ex){ 

 ex.printStackTrace(); 

 logger.error("出错了!",ex); 

 } 

 } 


/******* 

 * 删除本月以外的日志信息 

 * @throws ParseException 

 */ 

 public void deleteDateOperatorLog() throws ParseException { 

 //先得到日 

 String today = OperatorDate.operatorLogDay(); 

 String sql=""; 

 if("01".equals(today)){ 

 //得到当前月份 

 String targetDate =OperatorDate.operatorLogDate(); 

 sql = "delete from i_xt_operatelog where operateTime < "+"'"+targetDate+"'"; 

 try{ 

 operateLogDao.deleteAll(sql); 

 }catch (Exception ex) { 

 ex.printStackTrace(); 

 logger.error("出错了!",ex); 

 } 

 } 

 // System.out.println("sql:"+sql); 

 } 



 /********** 

 * @condition 查询条件 

 * @start 显示记录的开始位置 

 * @limit 每页显示的记录条数 

 * @response 客户端写数据的对象 

 */ 

 public void queryOperatorLog(String condition, int start, int limit, 

 HttpServletResponse response) { 

 String hql="from OperateLog log"; 

 boolean flag = false; 

 if(null==condition || condition.equals("输入查询条件")){ 

 hql="from OperateLog log"; 

 }else{ 

 flag = true; 

 hql +=" where log.operateName='"+condition+"'"; 

 } 

 //System.out.println(hql); 

 List<OperateLog> listOperateLog ; 

 int totalProperty=0; 

 try{ 

 listOperateLog = operateLogDao.queryByHQLForPagination(hql, start, limit); 

 if(!flag){ 

 totalProperty = this.queryOperatorLogCount(); 

 }else{ 

 totalProperty =listOperateLog.size(); 

 } 

 PageUtil.pageSet(totalProperty, listOperateLog, response); 

 }catch(Exception ex){ 

 ex.printStackTrace(); 

 logger.error("出错了!",ex); 

 } 

} 


}



剩下的就是daoImpl和dao以及OperatorLog这个实体信息!dao操作都和以往是相同,增删改!自己看着实现下!
它对bizImpl中所有的方法进行拦截!然后进入切面类的loggin()的方法中,在这个方法中可以获取参数的信息,方法的名字!然后进行相应的保存写到数据库中就行了!这个功能没有对查询进行保存,查询操作太多了!对于一些关键的方法,主要实现记录。
最后还有一个问题:比如bizImpl中某个方法调用其它的工具类中的方法,就没有办法捕获了!比如:下面的例子findById()和delete就没办法捕获,想捕获它们就应该加在dao层上了!

//删除客户信息 

 public void deleteCustomer(int customerId){ 

 try{ 

 Customer customer = (Customer) customerDao.findById(cid); 

 customerDao.delete(customer); 

 }catch(Exception ex){ 

 ex.printStackTrace(); 

 logger.error("出错了!",ex); 

 } 


}