#Session和Cookie對象 Session和Cookie主要使用在會話管理中。 ###會話 ####什麼是會話? 簡單來講,用戶打開一個瀏覽器,點擊多個連接,訪問服務器的多個web資源,而後關閉瀏覽器,整個過程稱之爲一個會話。 會話指得是一段時間內,客戶端與服務器進行了連續的通信,而http協議是無狀態的,那麼服務器是如何識別請求的呢?答案就是Session與Cookie對象。 ####會話解決的問題java
request不太現實,由於每次請求都是獨立的,ServletContext仍是有但願的,可是分析後發現,也是不行的,會發生衝突問題。由於ServletContext被全部Servlet共享。咱們發現,若是有一個域對象,它沒有request那麼獨立,也沒有ServletContext那麼公用,而是在必定範圍內的共享,這個範圍就是一個用戶與服務器的一段時間的通信(打開瀏覽器,屢次訪問服務器,關閉瀏覽器)。web
###保存會話數據的兩種技術算法
####Cookie數組
![Cookie圖解][]瀏覽器
####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應用:顯示用戶上次瀏覽過的商品(注意的點:列表的個數,列表的排序,再次瀏覽已有商品後的排序)
> * 兩個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