Java學(xué)習(xí)

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

           

          HttpSessionListener 和HttpSessionBindingListener的區(qū)別(單點(diǎn)登陸時(shí)有用)

          8.1. 使用HttpSessionListener

          編寫(xiě)一個(gè)OnlineUserListener。

          package anni;

          import java.util.List;
          import javax.servlet.ServletContext;
          import javax.servlet.http.HttpSession;
          import javax.servlet.http.HttpSessionListener;
          import javax.servlet.http.HttpSessionEvent;

          public class OnlineUserListener implements HttpSessionListener {

          public void sessionCreated(HttpSessionEvent event) {
          }

          public void sessionDestroyed(HttpSessionEvent event) {
          HttpSession session = event.getSession();
          ServletContext application = session.getServletContext();

          // 取得登錄的用戶(hù)名
          String username = (String) session.getAttribute("username");

          // 從在線(xiàn)列表中刪除用戶(hù)名
          List onlineUserList = (List) application.getAttribute("onlineUserList");
          onlineUserList.remove(username);

          System.out.println(username + "超時(shí)退出。");
          }

          }

          OnlineUserListener實(shí)現(xiàn)了HttpSessionListener定義的兩個(gè)方法:sessionCreated()和 sessionDestroyed()。這兩個(gè)方法可以監(jiān)聽(tīng)到當(dāng)前應(yīng)用中session的創(chuàng)建和銷(xiāo)毀情況。我們這里只用到 sessionDestroyed()在session銷(xiāo)毀時(shí)進(jìn)行操作就可以。

          從HttpSessionEvent中獲得即將銷(xiāo)毀的session,得到session中的用戶(hù)名,并從在線(xiàn)列表中刪除。最后一句向console打印一條信息,提示操作成功,這只是為了調(diào)試用,正常運(yùn)行時(shí)刪除即可。

          為了讓監(jiān)聽(tīng)器發(fā)揮作用,我們將它添加到web.xml中:

          <listener>
          <listener-class>anni.OnlineUserListener</listener-class>
          </listener>

          以下兩種情況下就會(huì)發(fā)生sessionDestoryed(會(huì)話(huà)銷(xiāo)毀)事件:

          1. 執(zhí)行session.invalidate()方法時(shí)。

            既然LogoutServlet.java中執(zhí)行session.invalidate()時(shí),會(huì)觸發(fā)sessionDestory()從在線(xiàn)用戶(hù) 列表中清除當(dāng)前用戶(hù),我們就不必在LogoutServlet.java中對(duì)在線(xiàn)列表進(jìn)行操作了,所以L(fǎng)ogoutServlet.java的內(nèi)容現(xiàn)在是 這樣。

            public void doGet(HttpServletRequest request,HttpServletResponse response)
            throws ServletException, IOException {
            // 銷(xiāo)毀session
            request.getSession().invalidate();
            // 成功
            response.sendRedirect("index.jsp");
            }
          2. 如果用戶(hù)長(zhǎng)時(shí)間沒(méi)有訪(fǎng)問(wèn)服務(wù)器,超過(guò)了會(huì)話(huà)最大超時(shí)時(shí)間,服務(wù)器就會(huì)自動(dòng)銷(xiāo)毀超時(shí)的session。

            會(huì)話(huà)超時(shí)時(shí)間可以在web.xml中進(jìn)行設(shè)置,為了容易看到超時(shí)效果,我們將超時(shí)時(shí)間設(shè)置為最小值。

            <session-config>
            <session-timeout>1</session-timeout>
            </session-config>

            時(shí)間單位是一分鐘,并且只能是整數(shù),如果是零或負(fù)數(shù),那么會(huì)話(huà)就永遠(yuǎn)不會(huì)超時(shí)。

          對(duì)應(yīng)例子在08-01,為了驗(yàn)證OnlineUserListener是否能正常執(zhí)行,我們可以登錄兩個(gè)用戶(hù),其中一個(gè)點(diǎn)擊注銷(xiāo),另一個(gè)等待一分鐘,然后可以在console中看到輸出的信息。

          470)this.style.width=470" align=center>

          8.2. 使用HttpSessionBindingListener

          HttpSessionBindingListener雖然叫做監(jiān)聽(tīng)器,但使用方法與HttpSessionListener完全不同。我們實(shí)際看一下它是如何使用的。

          我們的OnlineUserBindingListener實(shí)現(xiàn)了HttpSessionBindingListener接口,接口中共定義了兩個(gè)方法:valueBound()和valueUnbound(),分別對(duì)應(yīng)數(shù)據(jù)綁定,和取消綁定兩個(gè)事件。

          所謂對(duì)session進(jìn)行數(shù)據(jù)綁定,就是調(diào)用session.setAttribute()把HttpSessionBindingListener保存進(jìn)session中。我們?cè)贚oginServlet.java中進(jìn)行這一步。

          // 把用戶(hù)名放入在線(xiàn)列表
          session.setAttribute("onlineUserBindingListener", new OnlineUserBindingListener(username));

          這就是HttpSessionBindingListener和HttpSessionListener之間的最大區(qū)別: HttpSessionListener只需要設(shè)置到web.xml中就可以監(jiān)聽(tīng)整個(gè)應(yīng)用中的所有session。 HttpSessionBindingListener必須實(shí)例化后放入某一個(gè)session中,才可以進(jìn)行監(jiān)聽(tīng)。

          從監(jiān)聽(tīng)范圍上比較,HttpSessionListener設(shè)置一次就可以監(jiān)聽(tīng)所有session,HttpSessionBindingListener通常都是一對(duì)一的。

          正是這種區(qū)別成就了HttpSessionBindingListener的優(yōu)勢(shì),我們可以讓每個(gè)listener對(duì)應(yīng)一個(gè)username,這樣 就不需要每次再去session中讀取username,進(jìn)一步可以將所有操作在線(xiàn)列表的代碼都移入listener,更容易維護(hù)。

          valueBound()方法的代碼如下:

          public void valueBound(HttpSessionBindingEvent event) {
          HttpSession session = event.getSession();
          ServletContext application = session.getServletContext();

          // 把用戶(hù)名放入在線(xiàn)列表
          List onlineUserList = (List) application.getAttribute("onlineUserList");
          // 第一次使用前,需要初始化
          if (onlineUserList == null) {
          onlineUserList = new ArrayList();
          application.setAttribute("onlineUserList", onlineUserList);
          }
          onlineUserList.add(this.username);
          }

          username已經(jīng)通過(guò)構(gòu)造方法傳遞給listener,在數(shù)據(jù)綁定時(shí),可以直接把它放入用戶(hù)列表。

          與之對(duì)應(yīng)的valueUnbound()方法,代碼如下:

          public void valueUnbound(HttpSessionBindingEvent event) {
          HttpSession session = event.getSession();
          ServletContext application = session.getServletContext();

          // 從在線(xiàn)列表中刪除用戶(hù)名
          List onlineUserList = (List) application.getAttribute("onlineUserList");
          onlineUserList.remove(this.username);

          System.out.println(this.username + "退出。");
          }

          這里可以直接使用listener的username操作在線(xiàn)列表,不必再去擔(dān)心session中是否存在username。

          valueUnbound的觸發(fā)條件是以下三種情況:

          1. 執(zhí)行session.invalidate()時(shí)。

          2. session超時(shí),自動(dòng)銷(xiāo)毀時(shí)。

          3. 執(zhí)行session.setAttribute("onlineUserListener", "其他對(duì)象");或session.removeAttribute("onlineUserListener");將listener從session中刪除時(shí)。

          因此,只要不將listener從session中刪除,就可以監(jiān)聽(tīng)到session的銷(xiāo)毀。

           

          (轉(zhuǎn)載...)

          posted on 2008-10-16 12:27 找個(gè)美女做老婆 閱讀(3586) 評(píng)論(0)  編輯  收藏


          只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


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

          導(dǎo)航

          統(tǒng)計(jì)

          公告

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

          常用鏈接

          留言簿(6)

          隨筆檔案

          文章檔案

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 醴陵市| 确山县| 如皋市| 札达县| 青浦区| 江口县| 武安市| 林周县| 图木舒克市| 两当县| 交口县| 霍林郭勒市| 青神县| 祁连县| 马尔康县| 武定县| 英德市| 襄城县| 阜南县| 彰武县| 彭水| 武定县| 上虞市| 隆化县| 高州市| 宣化县| 焦作市| 双城市| 左贡县| 鄂温| 金寨县| 永胜县| 太仆寺旗| 乐都县| 琼中| 漾濞| 沁水县| 中超| 车险| 门头沟区| 龙胜|