当前位置: 首页 > 图文教程 > 网络编程 > JSP > 使用xmlhttp和Java session监听改善站内消息系统

JSP
Java 创建cookie和删除cookie
jsp 从web.xml读取连接数据库的参数
jsp 不支持EL表达式,解决办法
jsp 获取客户端的浏览器和操作系统信息
struts2 session 解读
struts2 spring整合fieldError问题
jsp 生成验证码代码
搭建java WEB开发环境和应用
JSP 自定义标签
Java 区分文本中的中英文字符函数
通用JSP页面 jsp入门级文章
jsp struts1 标签实例详解
一个jdbc 测试程序代码
SSH整合中 hibernate托管给Spring得到SessionFactory
jsp SmartUpload 实现上传功能代码
jsp Unsupported encoding: gb2312 错误原因
java Struts2 在拦截器里的跳转问题
jsp 对request.getSession(false)的理解(附程序员常疏忽的一个漏洞)
Java 项目生成静态页面的代码
jdk与jre的区别 很形象,很清晰,通俗易懂

JSP 中的 使用xmlhttp和Java session监听改善站内消息系统


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-03   浏览: 70 ::
收藏到网摘: n/a

Bromon原创 请尊重版权

  这个题目含有许多需要解释的概念,最容易说明的是“站内消息”,这是很多论坛都有的功能,可以通过web向其他的在线用户发送消息,很多用户都使用过。站内消息的第一个好处是大家都不需要安装客户端,你不用知道对方的MSN或者QQ,就能与他联系,称赞他的观点或者是给他一顿臭骂。第二个好处是客户管理方便,利用session来维护在线名单,各种脚本都已经把session操作封装得很易用了,不用像其他无状态的即时通信工具(比如使用UDP通信的工具)一样,要费一些脑细胞来解决在线名单的问题。缺点嘛,就是实时性不好,一般是在用户跳转或者刷新页面才能探测消息、更新在线名单。

  Session监听嘛,没什么好解释的,java提供了很灵活的事件机制来监听session,可以监听session的创建和销毁,监控session所携带数据的创建、变化和销毁,可以监听session的锐化和钝化(了解对象序列化的兄弟应该知道这个),其他的平台是个什么情况我不太清楚,估计也差不多吧。如果能够对所有客户的session进行监控,就不用再去操作麻烦而危险的Application了。

  Xmlhttp是MS推的一项技术,功能很复杂,可以做很多事情,比如客户端可以在简单的HTML中打开HTTP连接,主动向server请求数据并获得返回数据,是DOM技术一个非常重要的应用,利用它来写无刷新的动态页面简直是so easy,做过web开发的兄弟应该明白它的意义有多么重大。

一、 session监听

  servlet中对session的监听有很多接口,功能很灵活,最常用的是监听Session和Attribute。这里要澄清一下概念,servlet中的session监听和Attribute监听含义有差别,session监听指的不是我们一般所理解的放置一个session或者销毁一个session,这是Attribute监听的功能,因为servlet中放置session的语法是session.setAttribute(“session名”,要放入的对象)。而session监听,监听的是HTTP连接,只要有用户与server连接,就算连接的是一个空白的jsp页面,也会触发session事件,所以此处的session实际上指的是connection,用来统计当前在线用户数最合适了。不知道我说清楚了没有。下面分别讲解这两种监听方式。

1、 session监听

  首先编写一个session监听类,实作HttpSessionListener接口,它的作用是计算当前有多少个在线用户:

  1. /**
  2. *@Author bromon
  3. *2004-6-12
  4. */
  5. package org.bromon.test;
  6. import javax.servlet.*;
  7. import javax.servlet.http.*;
  8. public class SessionCount implements HttpSessionListener
  9. {
  10.     private static int count=0;
  11.     public void sessionCreated(HttpSessionEvent se)
  12.     {
  13.         count++;
  14.         System.out.println(“session创建:”+new java.util.Date());
  15.     }
  16.     public void sessionDestroyed(HttpSessionEvent se)
  17.     {
  18.        count--;
  19.        System.out.println(“session销毁:”+new java.util.Date());
  20.     }
  21.     public static int getCount()
  22.     {
  23.        return(count);
  24.      }
  25. }



  怎么样,是不是一目了然?count被定义为static,是因为要保证整个系统只有这一个count。如果你实在不放心,可以把它写成一个单例类。

  然后在web.xml中声明这个监听器:
<listener>
<listener-class>
org.bromon.test.SessionCount
</listener-class>
</listener>

  编写一个测试页面test.jsp,内容是获得count:
<%
int count=org.bromon.test.SessionCount.getCount();
out.println(count);
%>

  需要注意的是,这里根本不涉及任何session的操作。重启动App server,试着连接test.jsp,可以看到监听器已经开始工作。

2、 Attribute监听
  作为一个站内消息系统,肯定要获得所有登陆者的ID,才有可能互发消息。这就涉及Attribute监听。假设我们写了个用户登陆的模块,用户通过身份验证之后会产生一个session,保存它的相关信息,比如:
  1. //check.jsp
  2. <%
  3.     String name=request.getParameter(“name”);
  4.     Name=new String(name.getBytes(“ISO8859-1”));
  5.     session.setAttribute(“user”,name);
  6. %>


  做过jsp的兄弟应该对这段代码再熟悉不过了,下面写个监听器来监听用户登陆,把所有用户的ID保存到一个List当中,这个监听器实作HttpSessionAttributeListener接口:

  1. /**
  2. *@Author bromon
  3. *2004-6-12
  4. */
  5. package org.bromon.test;
  6. import javax.servlet.*;
  7. import javax.servlet.http.*;
  8. import java.util.*;
  9. public class OnlineList implements HttpSessionAttributeListener
  10. {
  11.     private static List list=new ArrayList();
  12.     public void attributeAdded(HttpSessionBindingEvent se)
  13.     {
  14.         if(“user”.equals(se.getName()))
  15.         {
  16.             list.add(se.getValue());
  17.          }
  18.     }
  19.     public void attributeRemoved(HttpSessionBindingEvent se)
  20.     {
  21.          if(“user”.equals(se.getName()))
  22.          {
  23.             list.remove(se.getValue());
  24.          }
  25.     }
  26.     public void attributeReplaced(HttpSessionBindingEvent se){}
  27.     public static List getList()
  28.     {
  29.          return(list);
  30.      }
  31. }


写个简单的jsp来得到用户列表:
<%
    java.util.List list=org.bromon.test.OnlineList.getList();
    out.println(“共有”+list.size()+”名用户已登陆:”);
    for(int I=0;I<lise.size();i++)
    {
        out.println(list.get(i));
    }
%>

也许你说,这有什么神奇呢,监听session而已,不着急,看看xmlhttp。

二、 XMLHTTP

  XMLHTTP的用处很多,这里只说我们需要的,就是无刷新的与server通信,看这段代码:

  1. <script language="javascript"
  2. xml = new ActiveXObject("Microsoft.XMLHTTP"); 
  3. var post=" ";//构造要携带的数据 
  4. xml.open("POST","http://localhost:7001/TestWL/index.jsp",false);//使用POST方法打开一个到服务器的连接,以异步方式通信 
  5. xml.setrequestheader("content-length",post.length); 
  6. xml.setrequestheader("content-type","application/x-www-form-urlencoded"); 
  7. xml.send(post);//发送数据 
  8. var res = xml.responseText;//接收服务器返回的数据 
  9. document.write(res); 
  10. </script>



  豁然开朗,这段代码就是打开一个HTTP连接,以标准的HTTP格式传递数据,如果你喜欢,可以用XML的格式来传递。更改一下xml对象的构造方式就可以兼容Mozilla和Netscape。下面来写一个轮询,每隔一段时间刷新一次用户列表,当然,是不需要刷新页面的:

  1. <html>
  2. <head><title>探测器</title>
  3. <script language="javascript">
  4. function detect()
  5. {
  6. xml = new ActiveXObject("Microsoft.XMLHTTP"); 
  7. var post=" ";//构造要携带的数据 
  8. xml.open("POST","http://localhost:7001/TestWL/index.jsp",false);//使用POST方法打开一个到服务器的连接,以异步方式通信 
  9. xml.setrequestheader("content-length",post.length); 
  10. xml.setrequestheader("content-type","application/x-www-form-urlencoded"); 
  11. xml.send(post);//发送数据 
  12. var res = xml.responseText;//接收服务器返回的数据 
  13. list.innerText=res;
  14. setTimeout(“detect()”,5000);//每隔5秒钟轮询一次
  15. </script>
  16. <body onload=”detect()”>
  17. <a id=”list”></a>
  18. </body>
  19. </html>


  这样的通信方式数据量很小,不用重新传递整个页面,5秒钟轮一次,普通PC也能承受较大的在线数。构造一个探测器来监听在线列表和消息,效果是很好的,即使你的客户坐在电脑前袖手旁观,键鼠都不碰一下,也能保证数据即时传递,页面也不会发生跳转和刷新。

  Session监听加上XMLHTTP通信,开发一个较为完善的站内消息系统实在易如反掌。