日志组件的编写 
 主要实现的几个功能:  1 操作的记录的处理理.  2 处理的灵活多样化.  3 使用的主便性. 
 首先,定义了一个接口Log,功能为: addLog添加一条日志记录. addLogFactory removeLogFactory getFactory添加/移除/获取日志处理工厂 setFinalFactory getFinalFactory 设置/获取最终日志处理工厂.  下面看一下LogFactory接口功能   isAccept某条记录是否由日志处理工厂的处理.   processLog处理日志记录  LogItem(日志项目)的功能如下.   getInput获取取操作时送过来的参数   getOldData获取旧数据(在更新数据时有用)   getStaticItem获取静态的数据(比如,用户名,IP等,比较固定的信息) 
 LogItem的实现如LogItemImpl所示.可以根据自己的实际需要重新继承LogItem.  LogFactory的实现如DBLogFactory所示.DBLogFactory实现的功能是把日志记录写到数据库中去.使用时LogFactory是要重新继承的部分,参照DBLogFactory即可.  Log的实现现AbstractLog实现了Log的大部分方法(除了addLog以外),基本上可以不用再继承Log,只要继承AbstractLog即可.  SwanLog是Log的一个具体实现一般情况下已经够用.不够的话可以自己承继AbstractLog类即可.    以上的类实现以后剩下的就是使用的问题了.  先来测试运行的情况,我是使用postgresql作为测试的,大家可以把DBLogFactory里的getConnection改成自己的连接.因为写到数据库的表名为tbllog我把tbllog的建表SQL放到附件最后,可以用该语句建立表先.  然后运行SwanLog可以看到数据表中插入了一条记录.  到此为止该日志已经可以用了,剩下的就是使用中的问题了.  相信大家都想在编写程序时不用管Log的问题,只要把程序写好就可以自动建立Log了.下面是该日志添加到代码中的方法.  对WEB程序,直接用我已经写好的类RequestInput,直接从Request里获得Input,然后从session里获取得静态的属性(当然初始化时要先设置好).至于OldData就没什么好办法了. 然后在程序进行Post(或Get)方法之前把代码addLog.如果你的Servlet没继承类或者没有使工作流的话那么就麻烦了,要一个一个的加,如果已经有了那就很简单了直接加就行了.就改一个地方即可.  有的库的日志可能是存在多个表里面的,可以建立多个LogFactory就可以了,只要写一下isAccept方法即可.  对客户端程序或者是RMI…..的程序,最主要的任务就是实现Input方法,相信大家都有自己的数据封装方法,实现起来应该很方便的. 以下是代码供大家浏览,剩余的类如Input….大家可以在我的权限组件的附加代码里找到(最后一篇).如果有什么好建议请与我联系. ========================Log.java=============================== package org.fswan.log; 
/**  * @author Swan Fong  (方志文)  * E-mail: [email protected]  * Site: http://blog.csdn.net/fswan  * 2004-11-19 10:37:44  * 日志接口  */ public interface Log {  /**   * 添加日志记录   * @param item 日志项目   * @return 添加结果   */  public int addLog(LogItem item);  /**   * 添加日志处理工厂   * @param fac 日志处理工厂   */  public void addFactory(LogFactory fac);  /**   * 移除日志处理工厂   * @param fac 日志处理工厂   */  public void removeFactory(LogFactory fac);  /**   * 获取所有的日志处理工厂   * @return 日志处理工厂   */  public LogFactory[] getFactory();  /**   * 设置最终日志处理工厂   * @param fac 日志处理工厂   */  public void setFinalFactory(LogFactory fac);  /**   * 获取最终数据处理工厂   * @return 日志处理工厂   */  public LogFactory getFinalFactory(); } ============================LogItem.java================== package org.fswan.log; 
import org.fswan.Input; 
/**  * @author Swan Fong  (方志文)  * E-mail: [email protected]  * Site: http://blog.csdn.net/fswan  * 2004-11-19 11:17:26  * 日志项目  */ public interface LogItem {  /**   * 获取操作信息   * @return 操作信息   */  public Input getInput();  /**   * 获取原始数据   * @param prop 数据标识   * @return 数据   */  public String getOldData(String prop);  /**   * 获取静态数据   * @param prop 数据标识   * @return 数据   */  public String getStaticItem(String prop); } ==============================LogFactory.java========================== package org.fswan.log; 
/**  * @author Swan Fong  (方志文)  * E-mail: [email protected]  * Site: http://blog.csdn.net/fswan  * 2004-11-19 11:15:00  * 日志处理工厂  */ public interface LogFactory {  /**   * 该工厂是否能处理某一日志   * @param item 日志项目   * @return 能否处理   */  public boolean isAccept(LogItem item);  /**   * 处理日志,处理结果为有理数,不能为负数和0   * @param item 日志项目   * @return 处理结果   */  public int processLog(LogItem item); } =======================DBLogFactory.java ========================== package org.fswan.log; 
import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Timestamp; import java.util.Date; 
/**  * @author Swan Fong  (方志文)  * E-mail: [email protected]  * Site: http://blog.csdn.net/fswan  * 2004-11-19 14:25:14  * 这个日志工厂把数据存到数据库中,如果成功返回SUCCESS失败返回FAILURE  * 包含字段 IP,用户名,描述,时间,是否成功  * 表名为tbllog,对应的字段为 ip,user,description,date,returnvalue   *   */ public class DBLogFactory implements LogFactory {  /**   * 操作成功   */  public static final int SUCCESS = 1;  /**   * 操作失败   */  public static final int FAILURE = 2;  /* (non-Javadoc)   * @see org.fswan.log.LogFactory#doneLog(org.fswan.log.LogItem)   */  public int processLog(LogItem item)  {   Connection conn = getConnection();   try   {    PreparedStatement pst = conn.prepareStatement("insert into tbllog (ip,\"user\",description,processdate,retvalue) values(?,?,?,?,?)");    pst.setInt(1,ipToInt(item.getStaticItem("IP")));    pst.setString(2,item.getStaticItem("user"));    pst.setString(3,"It's Operate");    pst.setTimestamp(4,new Timestamp(new Date().getTime()));    pst.setInt(5,1);    pst.executeUpdate();    conn.close();    return 1;   }catch (SQLException e)   {    e.printStackTrace();   }   return 2;  } 
 /* (non-Javadoc)   * @see org.fswan.log.LogFactory#isAccept(org.fswan.log.LogItem)   */  public boolean isAccept(LogItem item)  {   return true;  }  /**   * 获取数据库连接   * @return 数据库联接   */  public Connection getConnection()  {   try   {        Class.forName("org.postgresql.Driver");    return DriverManager.getConnection("jdbc:postgresql://localhost:5432/hrms","fswan","314843");   } catch (ClassNotFoundException e)   {    e.printStackTrace();   } catch (SQLException e)   {    e.printStackTrace();   }   return null;  }  /**   * 把IP的字符串转成数字型   * @param ip IP的字符串表示   * @return IP对应的数字   */  public int ipToInt(String ip)  {   String[] ips = ip.split("\\.");    if(ips.length != 4)return -1;   int[] iip = new int[ips.length];   for (int i = 0; i < iip.length; i++)   {    iip[i] = Integer.parseInt(ips[i]);   }   return (iip[0]<<24) | (iip[1] << 16) | (iip[2] << 8) | iip[3];  } } ========================LogItemImpl.java===================== package org.fswan.log; 
import java.util.HashMap; import java.util.Properties; 
import org.fswan.Input; 
/**  * @author Swan Fong  (方志文)  * E-mail: [email protected]  * Site: http://blog.csdn.net/fswan  * 2004-11-19 14:17:04  *   */ public class LogItemImpl implements LogItem {  Input input;  HashMap map;  Properties staticItem;  public LogItemImpl(Input input,HashMap map,Properties staticItem)  {   this.input = input;   this.map = map;   this.staticItem = staticItem;  }  /* (non-Javadoc)   * @see org.fswan.log.LogItem#getInput()   */  public Input getInput()  {   return input;  } 
 /* (non-Javadoc)   * @see org.fswan.log.LogItem#getOldData(java.lang.String)   */  public String getOldData(String prop)  {   return ""+map.get(prop);  } 
 /* (non-Javadoc)   * @see org.fswan.log.LogItem#getStaticItem(java.lang.String)   */  public String getStaticItem(String prop)  {   return staticItem.getProperty(prop);  } 
} 
============================AbstractLog.java======================== package org.fswan.log; 
/**  * @author Swan Fong  (方志文)  * E-mail: [email protected]  * Site: http://blog.csdn.net/fswan  * 2004-11-19 11:37:24  *   */ public abstract class AbstractLog implements Log {  private LogFactory[] facs;  private LogFactory finalFactory;    /* (non-Javadoc)   * @see org.fswan.log.Log#addFactory(org.fswan.log.LogFactory)   */  public void addFactory(LogFactory fac)  {   if(fac == null) return;   if(facs == null)   {    facs = new LogFactory[1];    facs[0] = fac;   }    else   {    LogFactory[] fs = new LogFactory[facs.length+1];    System.arraycopy(facs,0,fs,0,facs.length);    fs[fs.length-1] = fac;    facs = fs;     }  } 
 /* (non-Javadoc)   * @see org.fswan.log.Log#getFactory()   */  public LogFactory[] getFactory()  {   return facs;  } 
 /* (non-Javadoc)   * @see org.fswan.log.Log#getFinalFactory()   */  public LogFactory getFinalFactory()  {   return finalFactory;  } 
 /* (non-Javadoc)   * @see org.fswan.log.Log#removeFactory(org.fswan.log.LogFactory)   */  public void removeFactory(LogFactory fac)  {   if(fac == null) return;   if(facs == null) return;   for (int i = 0; i < facs.length; i++)   {    if(facs[i] == fac)    {     LogFactory[] fs = new LogFactory[facs.length-1];     System.arraycopy(facs,0,fs,0,i);     System.arraycopy(facs,i+1,fs,i,fs.length-i);     facs = fs;     return;    }   }  } 
 /* (non-Javadoc)   * @see org.fswan.log.Log#setFinalFactory(org.fswan.log.LogFactory)   */  public void setFinalFactory(LogFactory fac)  {   finalFactory = fac;  } 
} ==========================SwanLog.java============================ package org.fswan.log; 
import java.util.Properties; 
 /**  * @author Swan Fong  (方志文)  * E-mail: [email protected]  * Site: http://blog.csdn.net/fswan  * 2004-11-19 11:49:27  * 实现的日志处理器,先在LogFactory里找到合适的处理器并进行处理,如果处理不了再在最终处理器处理,处理后的返回值是false  *   */ public class SwanLog extends AbstractLog {  public static final int HAVENTPROCESS = 0;  public SwanLog()  {   addFactory(new DBLogFactory());  }  /* 如果是factory进行处理的返回值为处理返回的值,如果是最终处理器处理返回值为处理返回值的负数   * (non-Javadoc)   * @see org.fswan.log.Log#addLog(org.fswan.log.LogItem)   */  public int addLog(LogItem item)  {   LogFactory[] fs = getFactory();   if(fs != null)   {    for (int i = 0; i < fs.length; i++)    {     if(fs[i].isAccept(item))     {      return fs[i].processLog(item);     }    }   }   LogFactory f = getFinalFactory();   if(f!=null)   if(f.isAccept(item))   {    return -f.processLog(item);   }   return HAVENTPROCESS;  }    public static void main(String[] args)  {   Properties p = new Properties();   p.setProperty("user","Swan");   p.setProperty("IP","202.192.133.145");   new SwanLog().addLog(new LogItemImpl(null,null,p));  } } 
==========================tbllog.script========================= CREATE TABLE tbllog (   ip int8,   "user" varchar(40),   description varchar(4000),   processdate timestamp,   retvalue int2 ) 
   
 
  |