Java學習

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

           

          HttpSession的正確理解

          關于HttpSession的誤解實在是太多了,本來是一個很簡單的問題,怎會搞的如此的復雜呢?下面說說我的理解吧:
          一個session就是一系列某用戶和服務器間的通訊。服務器有能力分辨出不同的用戶。一個session的建立是從一個用戶向服務器發第一個請求開始,而以用戶顯式結束或session超時為結束。
          其工作原理是這樣的:
          1.當一個用戶向服務器發送第一個請求時,服務器為其建立一個session,并為此session創建一個標識號;
          2.這個用戶隨后的所有請求都應包括這個標識號。服務器會校對這個標識號以判斷請求屬于哪個session
          這種機制不使用IP作為標識,是因為很多機器是通過代理服務器方式上網,沒法區分每一臺機器。
          對于session標識號(sessionID),有兩種方式實現:cookies和URL重寫。

          HttpSession的使用
          我們來看看在API中對session是如何定義和操作的。
          當需要為用戶端建立一個session時,servlet容器就創建了一個HttpSession對象。其中存儲了和本session相關的信息。所以,在一個servlet中有多少個不同用戶連接,就會有多少個HttpSession對象。
          使用的機理是:
          1.從請求中提取HttpSession對象;
          2.增加或刪除HttpSession中的屬性;
          3.根據需要關閉HttpSession或使其失效。

          在請求中有兩個重載的方法用來獲取HttpSession對象。
          HttpSession getSession(boolean create)/getSession();作用是提取HttpSession對象,如果沒有自動創建。

          獲取到HttpSession對象后,我們就需要使用HttpSession的某些方法去設置和更改某些參數了。如:
          void setAttribute(String name, Object value);
          Object getAttribute(String name);
          void removeAttribute(String name);

          在javax.servlet.http包里一共定義了四個session監聽器接口和與之關聯的兩個session事件。分別是:
          HttpSessionAttributeListener and HttpSessionBindingEvent;
          HttpSessionBindingListener and HttpSessionBindingEvent;
          HttpSessionListener and HttpSessionEvent;
          HttpSessionActivationListener and HttpSessionEvent.

          他們的繼承關系是:
          所有四個接口的父類是java.util.EventListener;
          HttpSessionEvent擴展java.util.EventObject;
          而HttpSessionBindingEvent又擴展了HttpSessionEvent。

          以下分別詳述:
          HttpSessionAttributeListener
          session中的屬性被添加,更改,刪除時得到通知。這個接口上節講過,主要看其它三個。

          HttpSessionBindingListener
          當一個實現了HttpSessionBindingListener的類被加入到HttpSession中(或從中移出)時,會產生HttpBindingEvent事件,而這些事件會被它本身接收到。
          本接口定義了兩個方法:
          void valueBound(HttpSessionBindingEvent e);
          void valueUnbound(HttpSessionBindingEvent e);
          當多個實現了HttpSessionBindingListener的類被加入到HttpSession中時,各類的方法只對本類感興趣,不會去理會其它類的加入。
          即使是同一類的不同實例間,也是互不關心的(各掃門前雪)。

          我們可以看到前兩個接口都對HttpSessionBindingEvent事件做出反應,但機理不同。
          HttpSessionAttributeListener是在web.xml中登記的,servlet容器僅創建一個實例,來為任何在session中增加屬性的servlet服務。觸發事件的對象是所有可以轉換為Object的實例。
          HttpSessionBindingListener不用在web.xml中登記,在每個servlet中用new創建實例,且僅對本實例向session中的加入(或移出)感興趣。觸發事件的對象僅僅是自己。

          HttpSessionListener
          對于session的創建和取消感興趣。需要在web.xml中登記。
          共有兩個方法:
          void sessionCreated(HttpSessionEvent se);
          void sessionDestroyed(HttpSessionEvent se);
          使用它我們可以容易的創建一個類來對session計數。


          也許我們會簡單的考慮使用sessionDestroyed方法來在session結束后做一些清理工作。但是,請注意,當這個方法被調用的時候,session已經結束了,你不能從中提取到任何信息了。因此,我們要另辟蹊徑。


          一種通常采用的方法是使用HttpSessionBindingListener接口。在session創建時增加一個屬性,而在session結束前最后一件事將這個屬性刪除,這樣就會觸發valueUnbound方法,所有對session的清理工作可以在這個方法中實現。

          HttpSessionActivationListener
          session在分布式環境中跨JVM時,實現該接口的對象得到通知。共兩個方法:
          void sessionDidActivate(HttpSessionEvent se);
          void sessionWillPassivate(HttpSessionEvent se);


          1、HTTP協議本身是“連接-請求-應答-關閉連接”模式的,是一種無狀態協議(HTTP只是一個傳輸協議);
          2、Cookie規范是為了給HTTP增加狀態跟蹤用的(如果要精確把握,建議仔細閱讀一下相關的RFC),但不是唯一的手段;
          3、所謂Session,指的是客戶端和服務端之間的一段交互過程的狀態信息(數據);這個狀態如何界定,生命期有多長,這是應用本身的事情;
          4、由于B/S計算模型中計算是在服務器端完成的,客戶端只有簡單的顯示邏輯,所以,Session數據對客戶端應該是透明的不可理解的并且應該受控于服務端;Session數據要么保存到服務端(HttpSession),要么在客戶端和服務端之間傳遞(Cookie或url rewritting或Hidden input);
          5、由于HTTP本身的無狀態性,服務端無法知道客戶端相繼發來的請求是來自一個客戶的,所以,當使用服務端HttpSession存儲會話數據的時候客戶端的每個請求都應該包含一個session的標識(sid, jsessionid 等等)來告訴服務端;
          6、會話數據保存在服務端(如HttpSession)的好處是減少了HTTP請求的長度,提高了網絡傳輸效率;客戶端session信息存儲則相反;
          7、客戶端Session存儲只有一個辦法:cookie(url rewritting和hidden input因為無法做到持久化,不算,只能作為交換session id的方式,即a method of session tracking),而服務端做法大致也是一個道理:容器有個session管理器(如tomcat的org.apache.catalina.session包里面的類),提供session的生命周期和持久化管理并提供訪問session數據的api;
          8、使用服務端還是客戶端session存儲要看應用的實際情況的。一般來說不要求用戶注冊登錄的公共服務系統(如google)采用cookie做客戶端session存儲(如google的用戶偏好設置),而有用戶管理的系統則使用服務端存儲。原因很顯然:無需用戶登錄的系統唯一能夠標識用戶的就是用戶的電腦,換一臺機器就不知道誰是誰了,服務端session存儲根本不管用;而有用戶管理的系統則可以通過用戶id來管理用戶個人數據,從而提供任意復雜的個性化服務;
          9、客戶端和服務端的session存儲在性能、安全性、跨站能力、編程方便性等方面都有一定的區別,而且優劣并非絕對(譬如TheServerSide號稱不使用HttpSession,所以性能好,這很顯然:一個具有上億的訪問用戶的系統,要在服務端數據庫中檢索出用戶的偏好信息顯然是低效的,Session管理器不管用什么數據結構和算法都要耗費大量內存和CPU時間;而用cookie,則根本不用檢索和維護session數據,服務器可以做成無狀態的,當然高效);
          10、所謂的“會話cookie”簡單的說就是沒有明確指明有效期的cookie,僅在瀏覽器當前進程生命期內有效,可以被后繼的Set-Cookie操作清除掉

          posted on 2008-10-16 12:41 找個美女做老婆 閱讀(3201) 評論(0)  編輯  收藏


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


          網站導航:
           

          導航

          統計

          公告

          本blog已經搬到新家了, 新家:www.javaly.cn
           http://www.javaly.cn

          常用鏈接

          留言簿(6)

          隨筆檔案

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 清水河县| 阳江市| 遂平县| 蒲城县| 通渭县| 邹城市| 准格尔旗| 顺昌县| 冕宁县| 黄陵县| 南和县| 遵化市| 土默特右旗| 社旗县| 无为县| 阿拉善左旗| 贡觉县| 庆云县| 曲阜市| 依兰县| 迭部县| 南漳县| 松桃| 江口县| 乐平市| 育儿| 治县。| 克拉玛依市| 华阴市| 阳原县| 光山县| 华坪县| 虹口区| 桓台县| 忻城县| 那曲县| 乳源| 疏勒县| 育儿| 青河县| 道真|