王力猛的博客

-=☆开发手记☆=-

老王ID:wallimn
29683次访问,排名3622(1)好友1人,关注者5
写过一些软件,VC、Delphi、Java都会一些,Oracle数据库也懂一点。这几年一直在同这些东西打交道。
wallimn的文章
原创 45 篇
翻译 0 篇
转载 7 篇
评论 71 篇
wallimn的公告

  我是一名编程爱好者,在此记录一些我编程过程中遇到的问题及解决方法,希望对遇到类似问题的朋友有所帮助。
  欢迎有共同爱好的朋友联系交流。
邮件:
wallimn@yahoo.cn
QQ:
54871876
MSN:
wallimn@hotmail.com
网络硬盘:
http://wallimn.ys168.com
最近评论
fromnpu:需要一个omdt的安装程序,邮箱asheng200325@qq.com,先行谢谢楼主了!
nino:牛,我顶,今天我也遇到这个问题~谢谢~
dongzheng:那个WORD签名插件在保存关闭之后再打开,好像插件就不透明了啊
dongzheng:老王,那个WORD
wallimn:实际情况下,图章是要盖住下面的文字的。
文章分类
收藏
    相册
    个人相册
    友情链拉
    我的博客2
    我的网络硬盘
    我老婆的博客
    存档
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 J2EE使用session监听实现在线用户明细及数量统计收藏

    新一篇: JSTL带参数查询分页方法

    /*************************************************************/ 
    /*
    wallimn原创文章,欢迎转载,转载请保留本文信息。
    博客:http://blog.csdn.net/wallimn    邮件:wallimn@sohu.com
    */
    /*************************************************************/ 

      思路很简单,但与网上多数文章有所不同。我使用两个监听器,通过HttpSessionListener监听用户退出事件,通过HttpSessionAttributeListener监听用户登录事件。一般来讲,用户登录,都是向session中写入一个登录用户名。因此,可以通过监听session属性的变化,得到用户登录的情况。监听器配制方法,就是在web.xml加入如下代码: 
     <listener>
      <listener-class>com.wallimn.onlinestat.SessionListener</listener-class>
     </listener>

      使用工厂模式来设计,定义一个保存用户登录信息的接口(IStatStore),以便可以通过多种机制保存用户登录信息,如内存(MemStat)或数据库(JdbcStat)。定义一个类厂(StoreFactory),来实现保存机制的切换。

      注:我在代码中,没有完成JdbcStat这个类,若哪位用我的方法,写了这个类,最好能通过邮件发给我。谢谢。

      以上是一些设计思想的简单介绍,下面把几个程序贴一下。

    SessionListener.java

    /**
     * 文件:SessionListener.java<br/>
     * 功能:<br/>
     * 编码:wallimn(Email: wallimn@sohu.com  QQ: 54871876)<br/>
     * 版本:V1.0<br/>
     * 时间:2008-3-25<br/>
     * 备注:此代码欢迎讨论,转载请保留以上信息。
     
    */

    package com.wallimn.onlinestat;

    import javax.servlet.http.HttpSessionAttributeListener;
    import javax.servlet.http.HttpSessionBindingEvent;
    import javax.servlet.http.HttpSessionEvent;
    import javax.servlet.http.HttpSessionListener;

    /**
     * session监听器,通过监听器来实现在线用户统计功能的类<br/>
     * 
     * 
    @version : V1.0<br/>
     * 
    @author : wallimn(Email: wallimn@sohu.com QQ: 54871876)<br/>
     * @date : 2008-3-25 上午09:41:11<br/>
     
    */

    public class SessionListener implements HttpSessionListener,
            HttpSessionAttributeListener 
    {
        
    /**
         * 这个值应该根据不同的应用,改成不同的值
         
    */

        
    private static final String LOGIN = "loginusername";

        
    /**
         * 功能描述: 编码时间:2008-3-25 上午09:41:11 参数及返回值:
         * 
         * 
    @param arg0
         * 
    @see javax.servlet.http.HttpSessionListener#sessionCreated(javax.servlet.http.HttpSessionEvent)
         
    */

        
    public void sessionCreated(HttpSessionEvent se) {
            
    // 时间: 2008-3-25 上午09:41:11
            System.out.println("Session创建:"+se.getSession().getId());
        }


        
    /**
         * 功能描述:session销毁监控,销毁时注销用户 编码时间:2008-3-25 上午09:41:11 参数及返回值:
         * 
         * 
    @param arg0
         * 
    @see javax.servlet.http.HttpSessionListener#sessionDestroyed(javax.servlet.http.HttpSessionEvent)
         
    */

        
    public void sessionDestroyed(HttpSessionEvent se) {
            
    // 时间: 2008-3-25 上午09:41:11
            String name = (String) se.getSession().getAttribute(LOGIN);
            System.out.println(
    "有人登出:"+name);
            
    if (name != null{
                StoreFactory.getStore().logoff(name);
            }

        }


        
    /**
         * 
         * 功能描述:监控用户登录。有登录的,记录其状态。
         * 编码时间:2008-4-3  上午10:58:36
         * 参数及返回值:
         *  
    @param event
         *  
    @see javax.servlet.http.HttpSessionAttributeListener#attributeAdded(javax.servlet.http.HttpSessionBindingEvent)
         
    */

        
    public void attributeAdded(HttpSessionBindingEvent event) {
            
    // 时间: 2008-3-25 上午09:55:42
            String name = event.getName();
            
    if (LOGIN.equals(name)) {
                StoreFactory.getStore().login((String) event.getValue());
                System.out.println(
    "有人登录:"+event.getValue());
            }

        }


        
    public void attributeRemoved(HttpSessionBindingEvent event) {
            
    // 时间: 2008-3-25 上午09:55:42
        }


        
    public void attributeReplaced(HttpSessionBindingEvent event) {
            
    // 时间: 2008-3-25 上午09:55:42
        }


    }

     接口:IStatStore.java 

    package com.wallimn.onlinestat;
    import java.util.List;
    /**
     * 在线人数统计的接口,可以使用多种方式实现,如:内存、数据库等,只要实现这个接口就可以了。
     *<br/>
     * 
    @version      :  V1.0<br/>
     * 
    @author       : wallimn(Email: wallimn@sohu.com  QQ: 54871876)<br/>
     * @date           : 2008-4-4 下午02:01:07<br/>
     
    */

    public interface IStatStore {
        
    /**
         * 记录登录状态
         *<br/>
         *编码:wallimn     时间:2008-4-3  上午10:08:05<br/>
         *参数及返回值:<br/>
         *  
    @param username
         
    */

        
    public void login(String username);
        
    /**
         * 取消登录状态
         *<br/>
         *编码:wallimn     时间:2008-4-3  上午10:08:17<br/>
         *参数及返回值:<br/>
         *  
    @param username
         
    */

        
    public void logoff(String username);
        
        
    /**
         * 返回登录用户及信息。
         *<br/>
         *编码:wallimn     时间:2008-4-3  上午10:20:08<br/>
         *参数及返回值:<br/>
         *  
    @return 链表里的对象是个数组,数组包含两个元素,0:用户名,1:登录时间。这样是为了便于为jstl标签处理
         
    */

        
    public List getUsers();
        
        
    /**
         * 在线用户数量
         *<br/>
         *编码:wallimn     时间:2008-4-4  下午01:52:55<br/>
         *参数及返回值:<br/>
         *  
    @return
         
    */

        
    public int getCount();
    }

     

    MemStat.java

    package com.wallimn.onlinestat;

    import java.util.Date;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Map;
    /**
     * 依托内存实现在线用户统计功能。适合于在线用户数量较少的情况。
     *<br/>
     * 
    @version      :  V1.0<br/>
     * 
    @author       : wallimn(Email: wallimn@sohu.com  QQ: 54871876)<br/>
     * @date           : 2008-4-4 下午01:53:36<br/>
     
    */

    public class MemStat implements IStatStore {

        
    private static Map userMap=null;
        
    static {
            userMap 
    = new HashMap();
        }


        
    public void login(String username) {
            
    //时间: 2008-4-3 上午10:09:13
            userMap.put(username, new Date());//如果存在,会覆盖已有的值
        }


        
    public void logoff(String username) {
            
    //时间: 2008-4-3 上午10:09:13
            userMap.remove(username);
        }


        
    public List getUsers() {
            
    //时间: 2008-4-3 上午10:23:34
            List list = new LinkedList();
            String user 
    = null;
            
    for(Iterator it = userMap.keySet().iterator();it.hasNext();){
                user 
    = (String) it.next();
                list.add(
    new Object[]{user,userMap.get(user)});
            }

            
    return list;
        }


        
    public int getCount() {
            
    //时间: 2008-4-4 下午01:53:25
            return userMap.size();
        }


    }

    类厂:StoreFactory.java

     

    package com.wallimn.onlinestat;

    public class StoreFactory {
        
    /**
         * 返回实现IStatStore接口的某种对象。
         *<br/>
         *编码:wallimn     时间:2008-4-3  上午10:54:05<br/>
         *参数及返回值:<br/>
         *  
    @return 实现IStatStore接口的某种对象
         
    */

        
    public static IStatStore getStore(){
            
    //这里应该设计成从配制文件中读取,暂时先这样写。
            
    //如果想在系统中使用jdbc的方式来实现统计功能,则返回JdbcStat对象即可。
            return new MemStat();
        }

    }

     

    页面上使用方法示例:

     

    <%@ page language="java" pageEncoding="GB18030" %>
    <%@ page import="com.wallimn.onlinestat.*" %>
    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    <%
        
    String path = request.getContextPath();
        
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
        request.setAttribute(
    "stat",StoreFactory.getStore().getUsers());
    %>
    <%--2007-9-20--%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
      
    <head>
        
    <base href="<%=basePath%>"/>    
        
    <title>在线用户统计</title>    
        
    <meta http-equiv="pragma" content="no-cache"/>
        
    <meta http-equiv="cache-control" content="no-cache"/>
        
    <meta http-equiv="expires" content="0"/>    
        
    <meta http-equiv="keywords" content="wallimn"/>
        
    <meta http-equiv="description" content="在线用户显示,wallimn,2008年4月"/>
        
    <style >
            h1
    {
                text-align
    :center;
                font-size
    :18px;
                margin-top
    :10px;
                margin-bottom
    :10px;
            
    }

            table
    {
                border-collapse
    :collapse;
                font-size
    :12px;
            
    }

            table,td,th
    {
                border
    :1px solid #EAEAEA;
            
    }

            th
    {
                height
    :28px;
            
    }

            td
    {
                height
    :24px;
                padding-left
    :1em;
            
    }

        
    </style>
        
    <script type="text/javascript">
        
    </script>
      
    </head>  
      
    <body>
          
    <h1>登录用户列表</h1>
          
    <table width="80%" align="center">
                   
    <tr>
                      
    <th>用户</th><th>登录时间</th>
                  
    </tr>
              
    <c:forEach items="${stat}" var="item">
                  
    <tr>
                      
    <td>${item[0]}</td><td>${item[1]}</td&g