會話技術概述
為了實現(xiàn)某一個功能(購物),瀏覽器和服務器之間可能會產(chǎn)生多次的請求和響應薄货。從打開瀏覽器訪問服務器開始,到訪問服務器結束關閉瀏覽器為止碍论,這期間產(chǎn)生的多次請求和響應加在一起就稱之為是瀏覽器和服務器之間的一次會話.
會話中的數(shù)據(jù)存儲問題
在一次會話中往往會產(chǎn)生一些數(shù)據(jù)谅猾,而這些數(shù)據(jù)是需要保存起來的员淫,如何在一次會話中保存所產(chǎn)生的數(shù)據(jù)呢?
如果需要保存會話中產(chǎn)生的數(shù)據(jù),可以考慮我們之前學習過的request域和ServletContext域:
(1)如果使用request作用域來保存會話中產(chǎn)生的數(shù)據(jù)瞎颗,由于會話是多次請求婉徘,多次響應,而request域的作用范圍僅僅是一次請求敬矩,所以用request域保存會話中產(chǎn)生的數(shù)據(jù)概行,作用范圍太小了!
(2)如果使用ServletContext作用域來保存會話中產(chǎn)生的數(shù)據(jù),ServletContext的作用范圍是整個WEB應用弧岳,如果將每一個客戶端和服務器產(chǎn)生的會話數(shù)據(jù)都保存在ServletContext域中凳忙,很可能會發(fā)生混亂.
[toc]
Cookie
Cookie是通過Set-Cookie響應頭和Cookie請求頭將會話中產(chǎn)生的數(shù)據(jù)保存在客戶端,是客戶端的技術
1.Cookie的工作原理
客戶端向服務器發(fā)送請求禽炬,服務器獲取需要保存的數(shù)據(jù)涧卵,并將需要保存的數(shù)據(jù)通過Set-Cookie響應頭發(fā)送給瀏覽器,瀏覽器會以Cookie的形式保存在瀏覽器的內(nèi)部.
當客戶端再次發(fā)送請求訪問服務器腹尖,服務器可以通過Cookie請求頭獲取上次發(fā)送給瀏覽器的Cookie信息柳恐,通過這種方式可以保存會話中產(chǎn)生的數(shù)據(jù).
由于Cookie技術是將會話中產(chǎn)生的數(shù)據(jù)保存在客戶端,每個客戶端各自持有自己的數(shù)據(jù)热幔,當需要時再帶給服務器乐设,因此不會發(fā)生混亂!
2.Cookie的API介紹
(1).創(chuàng)建Cookie對象
Cookie cookie = new Cookie(String name绎巨,String value);
(2).將Cookie對象添加到響應中
// 將指定的Cookie對象添加到響應中
// 最后隨響應發(fā)送給瀏覽器保存(底層還是通過set-Cookie響應頭將Cookie值發(fā)送給瀏覽器)
response.addCookie(Cookie cookie);
(3).獲取請求中的Cookie信息
// 返回請求中所有的Cookie對象組成的數(shù)組.
// 如果請求中沒有任何Cookie信息近尚,該方法將會返回null
request.getCookies();
(4).setMaxAge方法 – 設置Cookie的最大生存時間
(1)如果不設置該方法,Cookie默認是會話級別的Cookie,是保存在瀏覽器的內(nèi)存中. 隨著瀏覽器的關閉认烁,Cookie也會跟著銷毀.
(2)如果設置了該方法肿男,并且是一個有效的時間,Cookie將會以文件的形式保存在瀏覽器的臨時文件夾中却嗡。
(5).setPath - 設置Cookie被帶給服務器的路徑
如果希望瀏覽器在訪問當前web應用下任何一個資源時都可以帶著Cookie,可以將cookie的path設置成當前web應用的虛擬路徑舶沛。
cookie.setPath(request.getContextPath()+"/");
"/"作用:若當前web應用是缺省的web應用
(6).刪除Cookie
- 在Cookie的API中沒有提供直接刪除Cookie的方法.
1.我們可以間接刪除Cookie:可以向瀏覽器再發(fā)一個同名、同path窗价、同domain(如果前后都不設置如庭,則domain默認是相同的)的Cookie
2.由于瀏覽器是根據(jù)Cookie的名字+path+domain來區(qū)分一個Cookie的,如果兩個Cookie的名字+path+domain完全一致撼港,則瀏覽器會認為是同一個Cookie坪它,這時后發(fā)的Cookie會覆蓋之前發(fā)送的Cookie
3.而后發(fā)的Cookie只要設置setMaxAge方法值為0,瀏覽器收到之后也會將后發(fā)的Cookie立即刪除。
- 也可以選擇在瀏覽器端直接刪除相應的cookie.
/**刪除coolie演示
* @author: zn
* @time: 2018年8月20日,上午11:40:33
*/
public class CookieRemoved extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//刪除名稱為time帝牡,path為當前web應用虛擬路徑的cookie
//1.創(chuàng)建一個key=time的cookie
Cookie cookie = new Cookie("time","");
//2.設置cookie的path
cookie.setPath(request.getContextPath()+"/");
//3.設置cookie的存活時間
cookie.setMaxAge(0);
//4.將cookie發(fā)送給瀏覽器
response.addCookie(cookie);
response.getWriter().write("Cookie Delete Sccess!");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
(7).cookie常用方法
方法 | 相關描述 |
---|---|
getName() | 獲取Cookie的名字 |
getValue() | 獲取Cookie的值 |
setValue() | 設置Cookie的值 |
setMaxAge() | 設置Cookie的最大存活時間 |
setPath() | 設置Cookie的路徑 |
案例演示 - 在網(wǎng)頁上顯示上次訪問時間
/**在網(wǎng)頁上顯示上次訪問時間
* @author: zn
* @time: 2018年8月20日,上午10:12:25
*/
public class CookieDemo1 extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//0.處理響應正文亂碼
response.setContentType("text/html;charset=utf-8");
//1.獲取本次訪問時間
Date date = new Date();
//2.將本次訪問時間通過Cookie發(fā)送到瀏覽器保存
//>>創(chuàng)建cookie對象
Cookie cookie = new Cookie("time",date.toString());
//>>設置cookie最大存活時間
cookie.setMaxAge(3600*24);
//>>設置cookie的path為當前web應用虛擬路徑
cookie.setPath(request.getContextPath()+"/");
//>>將cookie添加到response中往毡,發(fā)送給瀏覽器保存
response.addCookie(cookie);
//3.獲取上次訪問時間
String dataTime = null;
//>>獲取請求中的所有cookie(對象組成的數(shù)組)
Cookie[] cookies = request.getCookies();
if(cookies!=null) {
//>>遍歷所有cookie,找出key=time的cookie
for(Cookie c : cookies) {
if("time".equals(c.getName())) {
dataTime = c.getValue();
}
}
}
//4.將上次訪問時間響應到瀏覽器中顯示
if(dataTime != null) {
response.getWriter().write("您上次訪問時間是 "+dataTime);
}else {
//用戶第一次訪問
response.getWriter().write("您是第一次訪問該網(wǎng)站");
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
Session
Session是將會話中產(chǎn)生的數(shù)據(jù)保存在服務端靶溜,是服務端的技術.
1.Session 原理
瀏覽器第一次發(fā)送請求需要保存數(shù)據(jù)時,服務端獲取到需要保存的數(shù)據(jù)开瞭,去服務器內(nèi)部檢查一下有沒有為當前瀏覽器服務的session懒震,如果有就直接拿過來用,如果沒有session就創(chuàng)建一個新的session拿過來用. 接著將數(shù)據(jù)保存在Session中嗤详,做出響應
當瀏覽器再去訪問服務器時个扰,服務器可以從session中獲取到之前為當前瀏覽器保存的數(shù)據(jù),通過這種方式葱色,也可以來==保存會話中產(chǎn)生的數(shù)據(jù)==递宅!
2.域?qū)ο螅篠ession
(1).域?qū)ο?/h5>
如果一個對象具有可以被看見的范圍,利用該對象上的map可以在整個范圍內(nèi)實現(xiàn)數(shù)據(jù)的共享.
方法 | 相關描述 |
---|---|
setAttribute() | |
getAttribute() | |
removeAttribute() | |
getAttributeNames() |
(2).生命周期
-
創(chuàng)建
當?shù)谝淮握{(diào)用request.getSession方法時苍狰,創(chuàng)建session對象
在調(diào)用request.getSession()/request.getSession(true)時办龄,如果服務器內(nèi)部為當前客戶端服務的session,就直接拿過來使用,如果沒有就創(chuàng)建一個新的session使用舞痰。
request.getSession(false):如果服務器內(nèi)部有為當前瀏覽器服務的session就直接拿過來使用土榴,如果沒有對應的session,就返回null响牛。
-
銷毀
a)超時銷毀:如果session 30分鐘沒有被使用玷禽,則會超時銷毀. 可以在web應用的web.xml文件中修改session的超時時間.
b)自殺:當調(diào)用session.invalidate方法時,將會立即銷毀session
c)意外身亡:當服務器非正常關閉時,session會銷毀!如果服務器正常關閉呀打,session將會以文件的形式保存在服務器的work目錄下矢赁,這個過程稱之為session的鈍化.
當服務器再次啟動時,鈍化著的session還可以再恢復回來贬丛,這個過程稱之為session的活化!
3.作用范圍
session作用范圍是整個會話范圍內(nèi)
4.功能
在整個會話范圍內(nèi)共享數(shù)據(jù)