會話技術
在瞭解cookie和session之前,需要先了解一個概念:會話
1. 概念
在日常生活中,從撥通電話到掛斷電話之間的一連串的你問我答的過程就是一個會話。web應用中的會話過程類似於生活中的打電話過程,它指的是客戶端(瀏覽器)與web服務器之間連續發生的一系列請求和響應的過程。例如:一個用戶在某個網站上的整個購物過程就是一個會話。
2. HttpServletRequest對象和ServletContext
HttpServletRequest對象和ServletContext都可以對數據進行保存,但是針對下面所描述的需求就不可行:
用戶甲和乙分別登錄購物網站,甲在購物車中添加了一個iphone手機,乙在購物車中添加了一個Ipad平板,這時web服務器需要對用戶甲和用戶乙的信息分別進行保存。
HttpServletRequest對象存儲爲什麼不能實現該需求呢?
客戶端請求web服務器時,針對每次HTTP請求,Web服務器都會創建一個HttpServletRequest對象,該對象只能保存本次請求所傳遞的數據。由於購買和結賬是兩個不同的請求,因此,在發送結賬請求時,之前購買的數據會丟失。
ServletContext對象爲什麼不能實現改需求呢
使用ServletContext對象保存數據時,由於同一個Web應用共享的是同一個ServletContext對象,因此,當用戶發送結賬請求時,由於無法區分哪些商品是哪個用戶所購買的,而會將該購物網站中的所有用戶購買的商品進行結算,這顯然也是不行的。
Cookie和Session
爲了保存會話過程中產生的數據,在Servlet技術中,提供了兩個用於保存會話數據的對象,分別是Cookie和Session。
3. 會話跟蹤
Cookie
1.概念
當用戶通過瀏覽器訪問Web服務器時,服務器會給客戶端發送一些信息,這些信息會保存在Cookie中。這樣,當瀏覽器再次訪問服務器時,會在請求頭中將Cookie發送給服務器,方便服務器對瀏覽器做出正確的響應。
服務器向客戶端發送Cookie時,會在HTTP響應頭中增加Set-Cookie響應頭信息。Set-Cookie頭字段中設置的Cookie遵循一定的語法格式,具體如下:
Set-cookie: color=red;Path=/;
在上述事例中:color表示Cookie的名稱,red表示Cookie的值,Path表示Cookie的屬性。
注意:Cookie必須以鍵值對的形式存在,其屬性可以有多個,但這些屬性之間必須用分號;和空格分隔。
2.Cookie的工作原理可這樣描述
1)首先瀏覽器向服務器發出請求。
2)服務器就會根據需要生成一個Cookie對象,並且把數據保存在該對象內。
3)然後把該Cookie對象放在響應頭,一併發送回瀏覽器。
4)瀏覽器接收服務器響應後,提出該Cookie保存在瀏覽器端。
5)當下一次瀏覽器再次訪問那個服務器,就會把這個Cookie放在請求頭內一併發給服務器。
6 ) 服務器從請求頭提取出該Cookie,判別裏面的數據,然後作出相應的動作。
3.Cookie 的增刪改查
(1)增加Cookie
//1:創建一個Cookie對象 ,只能存非中文的字符串
Cookie cookie1 = new Cookie("name", "zhangsan");
Cookie cookie2 = new Cookie("age", "35");
//2:將生成的Cookie發送到瀏覽器
response.addCookie(cookie1);
response.addCookie(cookie2);
(2)獲取Cookie
Cookie[] cookies = request.getCookies();
for (Cookie cookie : cookies) {
System.out.println(cookie.getName()+" " + cookie.getValue());
}
(3)設置Cookie中文:URLEncoder(編碼),URLDecoder(解碼)
- URLEncoder.encode(“張三”, “UTF-8”);//編碼
- URLDecoder.decode(cookie.getValue(), “UTF-8”);//解碼
添加Cookie
//對中文進行編碼
String str = URLEncoder.encode("張三", "UTF-8");
Cookie cookie = new Cookie("username", str); //"%ED%AC%11%FE" URL編碼
response.addCookie(cookie);
獲取Cookie
Cookie[] cookies = request.getCookies();
for (Cookie cookie : cookies) {
//對中文進行解碼
String str = URLDecoder.decode(cookie.getValue(), "UTF-8");
System.out.println(cookie.getName()+" " + str);
}
(4)設置Cookie持久化時間
Cookie cookie = new Cookie("username", "lisi");
/*
* 1:默認情況下,Cookie的聲明週期是從發送Cookie到瀏覽器結束
* 2:如果要對Cookie持久化,必須設置Cookie的存活時間,則Cookie存到硬盤中
* setMaxAge(expiry) 單位是秒
* 3:如果持久化了之後,瀏覽器關閉之後重啓可以重新獲取
*/
cookie.setMaxAge(60*60*24*365*100); //單位是秒
response.addCookie(cookie);
(5)設置Cookie作用域
Cookie cookie = new Cookie("username", "wangwu");
//設置Cookie訪問路徑:path
//1:只要訪問同一個Tomcat中所有的項目資源,都會攜帶Cookie
cookie.setPath("/");
//2:只要訪問我當前項目中的所有資源,都會攜帶Cookie1
cookie.setPath("/AiTest/");
//3:只要訪問我當前項目中的abc目錄下所有資源,都會攜帶Cookie
cookie.setPath("/AiTest/abc");
//cookie.setPath(request.getContextPath());
response.addCookie(cookie);
(6)刪除Cookie
//清除Cookie
Cookie cookie = new Cookie("username", "");
//1:設置訪問的路徑path, 這裏的Path必須和設置Cookie 的路徑保持一致
cookie.setPath(request.getContextPath());
//2:設置存活時間
cookie.setMaxAge(0);
//3:將cookie發送到瀏覽器
response.addCookie(cookie);
//刪除cookie就是將指定cookie存活時間設置爲0讓瀏覽器刪除
Session
1.概念
除了使用Cookie,Web應用程序中還經常使用Session來記錄客戶端狀態。Session是服務器端使用的一種記錄客戶端狀態的機制,使用上比Cookie簡單一些,相應的也增加了服務器的存儲壓力。
當瀏覽器訪問Web服務器時,Servlet容器就會創建一個Session對象和ID屬性,當客戶端後續訪問服務器時,只要將標識號傳遞給服務器,服務器就能判斷該請求是哪個客戶端發送的,從而選擇與之對應的Session對象爲其服務。
注意:由於客戶端需要接受、記錄和回送Session對象的ID,因此,通常情況下,Session是藉助Cookie技術來傳遞ID屬性的。
過程如下:
那麼Session技術的原理是什麼,它是如何工作的呢?
1)瀏覽器發出請求到服務器。
2)服務器會根據需求生成Session對象,並且給這個Session對象一個編號,一個編號對應一個Session對象
3)服務器把需要記錄的數據封裝到這個Session對象裏,然後把這個Session對象保存下來。
4)服務器把這個Session對象的編號放到一個Cookie裏,隨着響應發送給瀏覽器
5)瀏覽器接收到這個cookie就會保存下來
6)當下一次瀏覽器再次請求該服務器服務,就會發送該Cookie
7)服務器得到這個Cookie,取出它的內容,它的內容就是一個Session的編號!!!
8)憑藉這個Session編號找到對應的Session對象,然後利用該Session對象把保存的數據取出來!
2.Session的增刪改查
( 1 )添加Session
//1: 創建Session對象,並設置值
HttpSession session = request.getSession(); //服務器上map集合
session.setAttribute("username", "zhagnsan");
( 2 )獲取Session
//獲取Session
HttpSession session = request.getSession();
Object username = session.getAttribute("username");
System.out.println("username:"+username);
( 3 )刪除Session
HttpSession session = request.getSession();
//1.將指定session的value設置爲null
session.setAttribute("user",null);
//2.移除指定key的session
session.removeAttribute("username");
//3.銷燬當前session
session.invalidate();
( 4 )獲取Session編號ID
String id = session.getId(); //獲取Session的編號Id
3.Session的生命週期
Session保存在服務器端。爲了獲得更高的存取速度,服務器一般把Session放在內存裏。每個用戶都會有一個獨立的Session。如果Session內容過於複雜,當大量客戶訪問服務器時可能會導致內存溢出。因此,Session裏的信息應該儘量精簡。
Session在用戶第一次訪問服務器的時候自動創建。需要注意只有訪問JSP、Servlet等程序時纔會創建Session,只訪問HTML、IMAGE等靜態資源並不會創建Session。如果尚未生成Session,也可以使用request.getSession(true)強制生成Session。
Session生成後,只要用戶繼續訪問,服務器就會更新Session的最後訪問時間,並維護該Session。用戶每訪問服務器一次,無論是否讀寫Session,服務器都認爲該用戶的Session“活躍(active)”了一次。
4.Session的有效期
由於會有越來越多的用戶訪問服務器,因此Session也會越來越多。爲防止內存溢出,服務器會把長時間內沒有活躍的Session從內存刪除。這個時間就是Session的超時時間。如果超過了超時時間沒訪問過服務器,Session就自動失效了。
Session的超時時間爲maxInactiveInterval屬性,可以通過對應的getMaxInactiveInterval()獲取,通過setMaxInactiveInterval(longinterval)修改。
Session的超時時間也可以在Tomcat的config目錄下的web.xml中修改。
<session-config>
<session-timeout>30</session-timeout>
</session-config>
5.Session對瀏覽器的要求
雖然Session保存在服務器,對客戶端是透明的,它的正常運行仍然需要客戶端瀏覽器的支持。這是因爲Session需要使用Cookie作爲識別標誌。HTTP協議是無狀態的,Session不能依據HTTP連接來判斷是否爲同一客戶,因此服務器向客戶端瀏覽器發送一個名爲JSESSIONID的Cookie,它的值爲該Session的id(也就是HttpSession.getId()的返回值)。Session依據該Cookie來識別是否爲同一用戶。
該Cookie爲服務器自動生成的,它的maxAge屬性一般爲–1,表示僅當前瀏覽器內有效,並且各瀏覽器窗口間不共享,關閉瀏覽器就會失效。
因此同一機器的兩個瀏覽器窗口訪問服務器時,會生成兩個不同的Session。但是由瀏覽器窗口內的鏈接、腳本等打開的新窗口(也就是說不是雙擊桌面瀏覽器圖標等打開的窗口)除外。這類子窗口會共享父窗口的Cookie,因此會共享一個Session。
注意:新開的瀏覽器窗口會生成新的Session,但子窗口除外。子窗口會共用父窗口的Session。例如,在鏈接上右擊,在彈出的快捷菜單中選擇“在新窗口中打開”時,子窗口便可以訪問父窗口的Session。
Cookie和Session的區別
從存儲方式上比較
Cookie只能存儲字符串,如果要存儲非ASCII字符串還要對其編碼; Session可以存儲任何類型的數據,可以把Session看成是一個容器
cookie數據存放在客戶的瀏覽器上,session數據放在服務器上;
單個cookie在客戶端的限制是3K,就是說一個站點在客戶端存放的COOKIE不能超過3K;
從隱私安全上比較
Cookie存儲在瀏覽器中,對客戶端是可見的。信息容易泄露出去。如果使用Cookie,最好將Cookie加密
Session存儲在服務器上,對客戶端是透明的。不存在敏感信息泄露問題。
從有效期上比較
Cookie保存在硬盤中,只需要設置maxAge屬性爲比較大的正整數,即使關閉瀏覽器,Cookie還是存在的
Session的保存在服務器中,設置maxInactiveInterval屬性值來確定Session的有效期。並且Session依賴於名爲JSESSIONID的Cookie,該Cookie默認的maxAge屬性爲-1。如果關閉了瀏覽器,該Session雖然沒有從服務器中消亡,但也就失效了。
從對服務器的負擔比較
Session是保存在服務器的,每個用戶都會產生一個Session,如果是併發訪問的用戶非常多,是不能使用Session的,Session會消耗大量的內存。
Cookie是保存在客戶端的。不佔用服務器的資源。像baidu這樣的大型網站,一般都是使用Cookie來進行會話跟蹤。