Java學(xué)習(xí)

          java,spring,structs,hibernate,jsf,ireport,jfreechart,jasperreport,tomcat,jboss -----本博客已經(jīng)搬家了,新的地址是 http://www.javaly.cn 如果有對文章有任何疑問或者有任何不懂的地方,歡迎到www.javaly.cn (Java樂園)指出,我會盡力幫助解決。一起進(jìn)步

           

          xmlhttp和Java session監(jiān)聽改善消息系統(tǒng)

            這個(gè)題目含有許多需要解釋的概念,最容易說明的是“站內(nèi)消息”,這是很多論壇都有的功能,可以通過web向其他的在線用戶發(fā)送消息,很多用戶都使用 過。站內(nèi)消息的第一個(gè)好處是大家都不需要安裝客戶端,你不用知道對方的MSN或者QQ,就能與他聯(lián)系,稱贊他的觀點(diǎn)或者是給他一頓臭罵。第二個(gè)好處是客戶 管理方便,利用session來維護(hù)在線名單,各種腳本都已經(jīng)把session操作封裝得很易用了,不用像其他無狀態(tài)的即時(shí)通信工具(比如使用UDP通信 的工具)一樣,要費(fèi)一些腦細(xì)胞來解決在線名單的問題。缺點(diǎn)嘛,就是實(shí)時(shí)性不好,一般是在用戶跳轉(zhuǎn)或者刷新頁面才能探測消息、更新在線名單。

          Session監(jiān)聽嘛,沒什么好解釋的,java提供了很靈活的事件機(jī)制來監(jiān)聽session,可以監(jiān)聽session的創(chuàng)建和銷毀,監(jiān)控 session所攜帶數(shù)據(jù)的創(chuàng)建、變化和銷毀,可以監(jiān)聽session的銳化和鈍化(了解對象序列化的兄弟應(yīng)該知道這個(gè)),其他的平臺是個(gè)什么情況我不太 清楚,估計(jì)也差不多吧。如果能夠?qū)λ锌蛻舻膕ession進(jìn)行監(jiān)控,就不用再去操作麻煩而危險(xiǎn)的Application了。

          Xmlhttp是MS推的一項(xiàng)技術(shù),功能很復(fù)雜,可以做很多事情,比如客戶端可以在簡單的HTML中打開HTTP連接,主動向server請求數(shù)據(jù)并獲得 返回?cái)?shù)據(jù),是DOM技術(shù)一個(gè)非常重要的應(yīng)用,利用它來寫無刷新的動態(tài)頁面簡直是so easy,做過web開發(fā)的兄弟應(yīng)該明白它的意義有多么重大。

          一、 session監(jiān)聽

          servlet中對session的監(jiān)聽有很多接口,功能很靈活,最常用的是監(jiān)聽Session和Attribute。這里要澄清一下概念, servlet中的session監(jiān)聽和Attribute監(jiān)聽含義有差別,session監(jiān)聽指的不是我們一般所理解的放置一個(gè)session或者銷毀 一個(gè)session,這是Attribute監(jiān)聽的功能,因?yàn)閟ervlet中放置session的語法是session.setAttribute (“session名”,要放入的對象)。而session監(jiān)聽,監(jiān)聽的是HTTP連接,只要有用戶與server連接,就算連接的是一個(gè)空白的jsp頁 面,也會觸發(fā)session事件,所以此處的session實(shí)際上指的是connection,用來統(tǒng)計(jì)當(dāng)前在線用戶數(shù)最合適了。不知道我說清楚了沒有。 下面分別講解這兩種監(jiān)聽方式。

          1、 session監(jiān)聽

          首先編寫一個(gè)session監(jiān)聽類,實(shí)作HttpSessionListener接口,它的作用是計(jì)算當(dāng)前有多少個(gè)在線用戶:

          /**
          *@Author bromon
          *2004-6-12
          */
          package org.bromon.test;

          import javax.servlet.*;
          import javax.servlet.http.*;

          public class SessionCount implements HttpSessionListener
          {
          private static int count=0;

          public void sessionCreated(HttpSessionEvent se)
          {
          count++;
          System.out.println(“session創(chuàng)建:”+new java.util.Date());
          }

          public void sessionDestroyed(HttpSessionEvent se)
          {
          count--;
          System.out.println(“session銷毀:”+new java.util.Date());
          }

          public static int getCount()
          {
          return(count);
          }
          }

          怎么樣,是不是一目了然?count被定義為static,是因?yàn)橐WC整個(gè)系統(tǒng)只有這一個(gè)count。如果你實(shí)在不放心,可以把它寫成一個(gè)單例類。

          然后在web.xml中聲明這個(gè)監(jiān)聽器:
          <listener>
          <listener-class>
          org.bromon.test.SessionCount
          </listener-class>
          </listener>

          編寫一個(gè)測試頁面test.jsp,內(nèi)容是獲得count:
          <%
          int count=org.bromon.test.SessionCount.getCount();
          out.println(count);
          %>

          需要注意的是,這里根本不涉及任何session的操作。重啟動App server,試著連接test.jsp,可以看到監(jiān)聽器已經(jīng)開始工作。

          2、 Attribute監(jiān)聽

          作為一個(gè)站內(nèi)消息系統(tǒng),肯定要獲得所有登陸者的ID,才有可能互發(fā)消息。這就涉及Attribute監(jiān)聽。假設(shè)我們寫了個(gè)用戶登陸的模塊,用戶通過身份驗(yàn)證之后會產(chǎn)生一個(gè)session,保存它的相關(guān)信息,比如:

          //check.jsp
          <%
          String name=request.getParameter(“name”);
          Name=new String(name.getBytes(“ISO8859-1”));
          session.setAttribute(“user”,name);
          %>

          做過jsp的兄弟應(yīng)該對這段代碼再熟悉不過了,下面寫個(gè)監(jiān)聽器來監(jiān)聽用戶登陸,把所有用戶的ID保存到一個(gè)List當(dāng)中,這個(gè)監(jiān)聽器實(shí)作HttpSessionAttributeListener接口:

          /**
          *@Author bromon
          *2004-6-12
          */
          package org.bromon.test;

          import javax.servlet.*;
          import javax.servlet.http.*;
          import java.util.*;

          public class OnlineList implements HttpSessionAttributeListener
          {
          private static List list=new ArrayList();

          public void attributeAdded(HttpSessionBindingEvent se)
          {
          if(“user”.equals(se.getName()))
          {
          list.add(se.getValue());
          }
          }

          public void attributeRemoved(HttpSessionBindingEvent se)
          {
          if(“user”.equals(se.getName()))
          {
          list.remove(se.getValue());
          }
          }

          public void attributeReplaced(HttpSessionBindingEvent se){}

          public static List getList()
          {
          return(list);
          }
          }

          寫個(gè)簡單的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));
          }
          %>

          也許你說,這有什么神奇呢,監(jiān)聽session而已,不著急,看看xmlhttp。

          二、 XMLHTTP

          XMLHTTP的用處很多,這里只說我們需要的,就是無刷新的與server通信,看這段代碼:

          <script language="javascript">
          xml = new ActiveXObject("Microsoft.XMLHTTP");
          var post=" ";//構(gòu)造要攜帶的數(shù)據(jù)
          xml.open("POST","http://localhost:7001/TestWL/index.jsp",false);//使用POST方法打開一個(gè)到服務(wù)器的連接,以異步方式通信
          xml.setrequestheader("content-length",post.length);
          xml.setrequestheader("content-type","application/x-www-form-urlencoded");
          xml.send(post);//發(fā)送數(shù)據(jù)
          var res = xml.responseText;//接收服務(wù)器返回的數(shù)據(jù)
          document.write(res);
          </script>

          豁然開朗,這段代碼就是打開一個(gè)HTTP連接,以標(biāo)準(zhǔn)的HTTP格式傳遞數(shù)據(jù),如果你喜歡,可以用XML的格式來傳遞。更改一下xml對象的構(gòu)造方式就 可以兼容Mozilla和Netscape。下面來寫一個(gè)輪詢,每隔一段時(shí)間刷新一次用戶列表,當(dāng)然,是不需要刷新頁面的:

          <html>
          <head><title>探測器</title>
          <script language="javascript">
          function detect()
          {
          xml = new ActiveXObject("Microsoft.XMLHTTP");
          var post=" ";//構(gòu)造要攜帶的數(shù)據(jù)
          xml.open("POST","http://localhost:7001/TestWL/index.jsp",false);//使用POST方法打開一個(gè)到服務(wù)器的連接,以異步方式通信
          xml.setrequestheader("content-length",post.length);
          xml.setrequestheader("content-type","application/x-www-form-urlencoded");
          xml.send(post);//發(fā)送數(shù)據(jù)
          var res = xml.responseText;//接收服務(wù)器返回的數(shù)據(jù)
          list.innerText=res;
          setTimeout(“detect()”,5000);//每隔5秒鐘輪詢一次
          }
          </script>
          <body onload=”detect()”>
          <a id=”list”></a>
          </body>
          </html>

          這樣的通信方式數(shù)據(jù)量很小,不用重新傳遞整個(gè)頁面,5秒鐘輪一次,普通PC也能承受較大的在線數(shù)。構(gòu)造一個(gè)探測器來監(jiān)聽在線列表和消息,效果是很好的,即使你的客戶坐在電腦前袖手旁觀,鍵鼠都不碰一下,也能保證數(shù)據(jù)即時(shí)傳遞,頁面也不會發(fā)生跳轉(zhuǎn)和刷新。

          Session監(jiān)聽加上XMLHTTP通信,開發(fā)一個(gè)較為完善的站內(nèi)消息系統(tǒng)實(shí)在易如反掌。

          posted on 2008-10-16 10:44 找個(gè)美女做老婆 閱讀(204) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           

          導(dǎo)航

          統(tǒng)計(jì)

          公告

          本blog已經(jīng)搬到新家了, 新家:www.javaly.cn
           http://www.javaly.cn

          常用鏈接

          留言簿(6)

          隨筆檔案

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 卢湾区| 恭城| 灵宝市| 邳州市| 清水河县| 米泉市| 鄯善县| 高邮市| 平昌县| 西贡区| 锦州市| 新巴尔虎右旗| 高雄县| 杭锦旗| 宣武区| 宁河县| 星座| 曲靖市| 航空| 禄丰县| 瑞昌市| 芦溪县| 巍山| 随州市| 巨野县| 恭城| 利川市| 广灵县| 江川县| 繁峙县| 怀集县| 霍山县| 双柏县| 龙胜| 宜春市| 弥渡县| 汉中市| 邯郸市| 沈阳市| 南靖县| 滦平县|