(JavaEE-06)Session與Cookie

#Session和Cookie對象 Session和Cookie主要使用在會話管理中。 ###會話 ####什麼是會話? 簡單來講,用戶打開一個瀏覽器,點擊多個連接,訪問服務器的多個web資源,而後關閉瀏覽器,整個過程稱之爲一個會話。 會話指得是一段時間內,客戶端與服務器進行了連續的通信,而http協議是無狀態的,那麼服務器是如何識別請求的呢?答案就是Session與Cookie對象。 ####會話解決的問題java

  • 每一個用戶在使用瀏覽器與服務器進行會話的過程當中,不可避省得會各自產生一些數據,程序要想辦法爲每一個用戶保存這些數據,好比:用戶點擊超連接訪問一個Servlet購買了一件產品,咱們應該將該用戶購買的產品保存起來,後續當用戶再次點擊另外一個超連接訪問一個結帳Servlet的時候能使用以前購買的產品。(購物車)
  • 思路:保存在request中或者ServletContext中

request不太現實,由於每次請求都是獨立的,ServletContext仍是有但願的,可是分析後發現,也是不行的,會發生衝突問題。由於ServletContext被全部Servlet共享。咱們發現,若是有一個域對象,它沒有request那麼獨立,也沒有ServletContext那麼公用,而是在必定範圍內的共享,這個範圍就是一個用戶與服務器的一段時間的通信(打開瀏覽器,屢次訪問服務器,關閉瀏覽器)。web

###保存會話數據的兩種技術算法

####Cookie數組

  • Cookie是客戶端技術,程序把每一個用戶的數據以Cookie的形式寫給用戶各自的瀏覽器。當用戶使用瀏覽器再去訪問服務器的web資源時,就會攜帶各自的數據去訪問。這樣,web資源就能這對不一樣的用戶進行處理了。

![Cookie圖解][]瀏覽器

####Session緩存

  • Session是服務端技術,利用這個技術,服務器在運行時能夠爲每個用戶的瀏覽器建立一個其獨享的Session對象,因爲Session被用戶的瀏覽器獨享,因此用戶在訪問服務器的web資源時,能夠把各自的數據放在各自的session中,當用戶再去訪問服務器中的其它資源時,其它web資源再從用戶各自的Session中取出數據爲用戶服務。

![Session圖解][]服務器

從圖中能夠清楚得看到,每一個客戶端在服務器都有與之對應的Session對象爲其存儲數據。cookie

###Cookie API javax.servlet.http.Cookie類用於建立一個Cookie,response接口也中定義了一個addCookie方法,它用於在其響應頭中增長一個相應的Set-Cookie頭字段。 一樣,request接口中也定義了一個getCookies方法,它用於獲取客戶端提交的Cookie。 Cookie類的方法:網絡

  • public Cookie(String name,String value)
  • setValue與getValue方法,設置Cookie的值
  • setMaxAge與getMaxAge方法,設置Cookie的有效期,默認的有效期是會話範圍的,會話結束,Cookie結束(存在緩存中)
  • setPath與getPath方法,設置Cookie的有效目錄,例如:/demo,那麼訪問demo目錄下的全部web資源,都會攜帶Cookie。默認有效目錄,當前建立Cookie的程序的目錄
  • setDomain與getDomain方法,設置Cookie的有效域,例如: .sina.com,前面有點。這個方法實際用處不大,瀏覽器會阻止第三方Cookie,只識別本域中的Cookie
  • getName方法,獲取Cookie的名稱

####Cookie簡單應用:顯示用戶上次訪問時間。session

####瀏覽器容許每一個域名所包含的Cookie數量:

  • Microsoft指出InternetExplorer8增長cookie限制爲每一個域名50個,但IE7彷佛也容許每一個域名50個cookie。
  • Firefox每一個域名cookie限制爲50個。
  • Opera每一個域名cookie限制爲30個。
  • Safari/WebKit貌似沒有cookie限制。可是若是cookie不少,則會使header大小超過服務器的處理的限制,會致使錯誤發生。

####當不少的cookie被設置,瀏覽器如何去處理

  • Safari(能夠設置所有cookie,無論數量多少)
  • 當Cookie已達到限額,自動踢除最老的Cookie,以使給最新的Cookie一些空間。Internet Explorer和Opera使用此方法。
  • Firefox很獨特:雖然最後的設置的Cookie始終保留,但彷佛隨機決定哪些cookie被保留。彷佛沒有任何計劃(建議:在Firefox中不要超過Cookie限制)。

####不一樣瀏覽器間cookie總大小也不一樣

  • Firefox和Safari容許cookie多達4097個字節,包括名(name)、值(value)和等號。
  • Opera容許cookie多達4096個字節,包括:名(name)、值(value)和等號。
  • Internet Explorer容許cookie多達4095個字節,包括:名(name)、值(value)和等號。
  • 注:多字節字符計算爲兩個字節。在全部瀏覽器中,任何cookie大小超過限制都被忽略,且永遠不會被設置。

###Cookie的細節

  • 一個Cookie只能標識一種信息,它至少含有一個標識該信息的名稱(name)和設置的值(value)
  • 一個web站點能夠給一個web瀏覽器發送多個Cookie,一個web瀏覽器也能夠存儲多個web站點提供的Cookie
  • 若是建立了一個Cookie,並將它發送到瀏覽器,默認狀況下它是一個會話級別的Cookie(存儲在瀏覽器的內存中),用戶退出瀏覽器以後就被刪除。若是但願瀏覽器將該Cookie存儲在硬盤上,則須要使用maxAge,並給出一個以秒作單位的時間。將最大時效設置爲0,則是命令瀏覽器刪除該Cookie。
  • 注意,刪除Cookie時,path必須一致,不然不會刪除

####Cookie應用:顯示用戶上次瀏覽過的商品(注意的點:列表的個數,列表的排序,再次瀏覽已有商品後的排序)

> * 兩個Servlet,一個是查看全部商品的Servlet(顯示全部商品,顯示已經瀏覽過的商品)
> * 一個是顯示商品的詳情,而且把已經看過的商品加入Cookie

#Session

  • 在WEB開發中,服務器能夠爲每一個用戶瀏覽器建立一個會話對象(session對象),注意:一個瀏覽器獨佔一個session對象(默認狀況下)。所以,在須要保存用戶數據時,服務器程序能夠把用戶數據寫到用戶瀏覽器獨佔的session中,當用戶使用瀏覽器訪問其它程序時,其它程序能夠從用戶的session中取出該用戶的數據,爲用戶服務。

  • Session和Cookie的主要區別在於

    • Cookie是把用戶的數據寫給用戶的瀏覽器
    • Session技術把用戶的數據寫到用戶獨佔的session中
  • Session對象由服務器建立,開發人員能夠調用request對象的getSession方法獲得session對象

    • 使用Session實現簡單購物功能(注意重複添加商品的問題,使用重定向來處理)
  • 因爲實際用戶的需求,還須要作進一步處理(用戶不當心關閉了瀏覽器,數據丟失、開多個瀏覽器購買)

###Session實現原理 Session的原理很是簡單,Session的實現藉助了Cookie,每次在服務器建立一個Session,同時這個Session就會有一個SessionID,在響應時,這個ID會以Cookie的形式返回給瀏覽器,瀏覽器下次再訪問web服務器時,會帶上這個Cookie。在服務端,根據Cookie中的ID就能夠找到對應的Session,從而實現服務端的會話。

###多瀏覽器共享Session 對於同一個瀏覽器來講,新開窗口就至關於新開啓了會話(不一樣瀏覽器支持效果不同),爲了方便用戶操做,能夠實現Session的多瀏覽器共享(同一個瀏覽器)

緣由是由於Cookie是會話級別的,解決很簡單,覆蓋之前的Cookie,設置maxAge Session中存儲的對象須要序列化

###禁用Cookie後實現Session共享 若是客戶端禁用了Cookie,這個時候用戶每次訪問都會獲取一個全新的Session,就失去了會話的意義,這個時候可使用URL重寫技術來處理。

URL重寫 response. encodeRedirectURL(java.lang.String url),response. encodeURL(java.lang.String url) URL會自動檢測客戶端是否禁用Cookie

###Session失效 Session默認有效時間爲30分鐘,手動能夠配置和修改這個時限。

配置web.xml 手動殺死Session

###Session案例

  • Session實現登陸驗證
  • Session實現一次性驗證碼(response驗證碼)
  • 表單的重複提交
>    * 在客戶端防止表單重複提交(讓提交失效、按鈕只能點擊一次)
>    * 在服務端防止表單重複提交(表單必須是動態由程序產生,表單中攜帶隨機數;令牌)
>    * 令牌能夠設計成一個單獨的類(單例),負責產生隨機數(毫秒數+隨機數,這樣產生的隨機數長度有可能不一致,可使用數據指紋,MD5算法(數據摘要,不可逆),MD5經常使用於密碼的保存、文件校驗碼)
>    * MD5碼的生成,可使用Java中的**MessageDigest**類來實現

    //產生一個隨機數
    String token = System.currentTimeMillis() + "" + new Random().nextInt(99999);
    //得到一個信息摘要對象,指定使用MD5算法來處理
    MessageDigest messageDigest = MessageDigest.getInstance("md5");
    //獲取根據MD5算法處理的結果字節數組
    //該數據將是一個128位的數據,一共128位,至關於16個字節,而這16個字節中表示的數字,在UTF-8碼錶中頗有多是沒有的
    byte[] md5 = messageDigest.digest(token.getBytes("UTF-8"));
    //將字節數據轉換成字符輸出
    //String s = new String(md5,"UTF-8");
    //這裏將出現亂碼,由於數字不在UTF-8的範圍中
    //System.out.println(s);
     
    //使用base64來將md5數據明文化
    BASE64Encoder encoder = new BASE64Encoder();
    String s = encoder.encode(md5);
    System.out.println(s);
  • 要想讓MD5的數據成爲明文,須要使用base64編碼(網絡傳輸經常使用的編碼)來完成,base64生成的各類能夠認識的字母 > * base64原理:base64的原理很簡單,它將三字節的書變成4個字節。三個字節一共24個二進制位,變成四個字節,那麼每一個字節只有6個二進制位,而後使用「0」來填補最高的兩個二進制位,這樣的話,每一個字節的範圍就是(00000000-00111111),0到63,一共64個數,而後有一張碼錶,一共就64個字符,這64個字符都是明文。

###存儲域的選擇 能存小域不要用大域 一次請求產生的數據就此次用,使用Request 一次請求產生的數據過一會還要用,使用Session 一次請求產生的數據不但過一會要用,並且別處還要用,使用ServletContext [Cookie圖解]: http://ww2.sinaimg.cn/mw690/5ae9e02djw1ehssrdjy31j20m80ce75a.jpg [Session圖解]: http://ww2.sinaimg.cn/mw690/5ae9e02djw1ehssrdqr1oj20l60bmgmg.jpg

相關文章
相關標籤/搜索