會(huì)話管理入門(mén)
-
軟件中的會(huì)話:
- 一次會(huì)話: 打開(kāi)瀏覽器 -> 訪問(wèn)一些服務(wù)器內(nèi)容 -> 關(guān)閉瀏覽器
- 登錄場(chǎng)景:打開(kāi)瀏覽器 -> 瀏覽到登陸頁(yè)面 -> 輸入用戶名和密碼 -> 訪問(wèn)到用戶主頁(yè)(顯示用戶名) -> 修改密碼(輸入原密碼)-> 修改收貨地址.......
問(wèn)題:在此處登錄會(huì)話過(guò)程中產(chǎn)生的數(shù)據(jù)(用戶會(huì)話數(shù)據(jù))如何保存下來(lái)呢?
-
購(gòu)物場(chǎng)景:
- 打開(kāi)瀏覽器 -> 瀏覽商品列表 -> 加入購(gòu)物車(把商品信息保存下來(lái)) -> 關(guān)閉瀏覽器
- 打開(kāi)瀏覽器-> 直接進(jìn)入購(gòu)物車 -> 查看到上次加入購(gòu)物車的商品 -> 下訂單 -> 支付
問(wèn)題: 在購(gòu)物會(huì)話過(guò)程中,如何保存商品信息炊汹??
會(huì)話管理: 管理瀏覽器客戶端和服務(wù)器端之間會(huì)話過(guò)程中產(chǎn)生的會(huì)話數(shù)據(jù)脚曾。
-
域?qū)ο螅?實(shí)現(xiàn)資源之間的數(shù)據(jù)共享
- request域?qū)ο?/li>
- context域?qū)ο?/li>
-
登錄場(chǎng)景:
- 小張 : 輸入“張三” (保存數(shù)據(jù): context.setAttribute("name","張三")) -> 用戶主頁(yè) (顯示“張三”)
- 小李 : 輸入“李四”(保存數(shù)據(jù):context.setAttribute("name","李四")) -> 用戶主頁(yè)(顯示“李四”)
問(wèn)題: context是所有用戶公有的資源!!會(huì)覆蓋數(shù)據(jù)
- 小張: 輸入“張三”(保存數(shù)據(jù): request.setAttribute("name","張三"))- > 用戶主頁(yè)(顯示“張三”)
問(wèn)題: 一定要使用轉(zhuǎn)發(fā)技術(shù)來(lái)跳轉(zhuǎn)頁(yè)面!
解決辦法: 可以使用session域?qū)ο髞?lái)保存會(huì)話數(shù)據(jù)袁铐!
會(huì)話技術(shù)
- Cookie技術(shù):會(huì)話數(shù)據(jù)保存在瀏覽器客戶端
- Session技術(shù):會(huì)話數(shù)據(jù)保存在服務(wù)器端
Cookie技術(shù)
- 特點(diǎn) : Cookie技術(shù):會(huì)話數(shù)據(jù)保存在瀏覽器客戶端
- 技術(shù)核心 : Cookie類:用于存儲(chǔ)會(huì)話數(shù)據(jù)
1)構(gòu)造Cookie對(duì)象 :Cookie(java.lang.String name, java.lang.String value)
2)設(shè)置cookie-
void setPath(java.lang.String uri)
: 設(shè)置cookie的有效訪問(wèn)路徑 -
void setMaxAge(int expiry)
: 設(shè)置cookie的有效時(shí)間 -
void setValue(java.lang.String newValue)
: 設(shè)置cookie的值
3)發(fā)送cookie到瀏覽器端保存 -
void response.addCookie(Cookie cookie)
: 發(fā)送cookie
4)服務(wù)器接收cookie :Cookie[] cookies= request.getCookies()
: 接收cookie
-
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
// 第一個(gè)cookie的程序
public class CookieDemo1 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//1.創(chuàng)建Cookie對(duì)象
Cookie cookie1 = new Cookie("name","eric");
//Cookie cookie2 = new Cookie("email","jacky@qq.com");
//Cookie cookie1 = new Cookie("email","eric@qq.com");
/**
* 1)設(shè)置cookie的有效路徑揭蜒。默認(rèn)情況:有效路徑在當(dāng)前web應(yīng)用下。 /day11
*/
//cookie1.setPath("/day11");
//cookie2.setPath("/day12");
/**
* 2)設(shè)置cookie的有效時(shí)間
* 正整數(shù):表示cookie數(shù)據(jù)保存瀏覽器的緩存目錄(硬盤(pán)中)剔桨,數(shù)值表示保存的時(shí)間屉更。
* 負(fù)整數(shù):表示cookie數(shù)據(jù)保存瀏覽器的內(nèi)存中。瀏覽器關(guān)閉cookie就丟失了H髯骸瑰谜!
* 零:表示刪除同名的cookie數(shù)據(jù)
*/
//cookie1.setMaxAge(20); //20秒,從最后不調(diào)用cookie開(kāi)始計(jì)算
cookie1.setMaxAge(-1); //cookie保存在瀏覽器內(nèi)存(會(huì)話cookie)
//cookie1.setMaxAge(0);
//2.把cookie數(shù)據(jù)發(fā)送到瀏覽器(通過(guò)響應(yīng)頭發(fā)送: set-cookie名稱)
//response.setHeader("set-cookie", cookie.getName()+"="+cookie.getValue()+",email=eric@qq.com");
//推薦使用這種方法树绩,避免手動(dòng)發(fā)送cookie信息
response.addCookie(cookie1);
//response.addCookie(cookie2);
//response.addCookie(cookie1);
//3.接收瀏覽器發(fā)送的cookie信息
/*
String name = request.getHeader("cookie");
System.out.println(name);
*/
Cookie[] cookies = request.getCookies();
//注意:判斷null,否則空指針
if(cookies!=null){
//遍歷
for(Cookie c:cookies){
String name = c.getName();
String value = c.getValue();
System.out.println(name+"="+value);
}
}else{
System.out.println("沒(méi)有接收cookie數(shù)據(jù)");
}
}
}
- Cookie原理
- 服務(wù)器創(chuàng)建cookie對(duì)象萨脑,把會(huì)話數(shù)據(jù)存儲(chǔ)到cookie對(duì)象中 :
new Cookie("name","value");
- 服務(wù)器發(fā)送cookie信息到瀏覽器 :
response.addCookie(cookie);
- 舉例 :
set-cookie: name=eric
: 隱藏發(fā)送了一個(gè)set-cookie名稱的響應(yīng)頭
- 瀏覽器得到服務(wù)器發(fā)送的cookie,然后保存在瀏覽器端饺饭。
- 瀏覽器在下次訪問(wèn)服務(wù)器時(shí)渤早,會(huì)帶著cookie信息
- 舉例 :
cookie: name=eric
: 隱藏帶著一個(gè)叫cookie名稱的請(qǐng)求頭
- 服務(wù)器接收到瀏覽器帶來(lái)的cookie信息 :
request.getCookies();
- 服務(wù)器創(chuàng)建cookie對(duì)象萨脑,把會(huì)話數(shù)據(jù)存儲(chǔ)到cookie對(duì)象中 :
- Cookie的細(xì)節(jié)
1)void setPath(java.lang.String uri)
: 設(shè)置cookie的有效訪問(wèn)路徑。有效路徑指的是cookie的有效路徑保存在哪里砰奕,那么瀏覽器在有效路徑下訪問(wèn)服務(wù)器時(shí)就會(huì)帶著cookie信息蛛芥,否則不帶cookie信息
2)void setMaxAge(int expiry)
: 設(shè)置cookie的有效時(shí)間。- 正整數(shù):表示cookie數(shù)據(jù)保存瀏覽器的緩存目錄(硬盤(pán)中)军援,數(shù)值表示保存的時(shí)間仅淑。
- 負(fù)整數(shù):表示cookie數(shù)據(jù)保存瀏覽器的內(nèi)存中。瀏覽器關(guān)閉cookie就丟失了P馗纭涯竟!
- 零:表示刪除同名的cookie數(shù)據(jù)
public class DeleteCookie extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/**
* 需求: 刪除cookie
*/
Cookie cookie = new Cookie("name","xxxx");
cookie.setMaxAge(0);//刪除同名的cookie
response.addCookie(cookie);
System.out.println("刪除成功");
}
}
3)Cookie數(shù)據(jù)類型只能保存非中文字符串類型的】昭幔可以保存多個(gè)cookie庐船,但是瀏覽器一般只允許存放300個(gè)Cookie,每個(gè)站點(diǎn)最多存放20個(gè)Cookie嘲更,每個(gè)Cookie的大小限制為4KB筐钟。
- 案例 : 顯示用戶上次訪問(wèn)的時(shí)間
public class HistServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
//獲取當(dāng)前時(shí)間
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String curTime = format.format(new Date());
//取得cookie
Cookie[] cookies = request.getCookies();
String lastTime = null;
if(cookies!=null){
for (Cookie cookie : cookies) {
if(cookie.getName().equals("lastTime")){
//有l(wèi)astTime的cookie,已經(jīng)是第n次訪問(wèn)
lastTime = cookie.getValue();//上次訪問(wèn)的時(shí)間
//第n次訪問(wèn)
//1.把上次顯示時(shí)間顯示到瀏覽器
response.getWriter().write("歡迎回來(lái)赋朦,你上次訪問(wèn)的時(shí)間為:"+lastTime+",當(dāng)前時(shí)間為:"+curTime);
//2.更新cookie
cookie.setValue(curTime);
cookie.setMaxAge(1*30*24*60*60);
//3.把更新后的cookie發(fā)送到瀏覽器
response.addCookie(cookie);
break;
}
}
}
/**
* 第一次訪問(wèn)(沒(méi)有cookie 或 有cookie篓冲,但沒(méi)有名為lastTime的cookie)
*/
if(cookies==null || lastTime==null){
//1.顯示當(dāng)前時(shí)間到瀏覽器
response.getWriter().write("你是首次訪問(wèn)本網(wǎng)站,當(dāng)前時(shí)間為:"+curTime);
//2.創(chuàng)建Cookie對(duì)象
Cookie cookie = new Cookie("lastTime",curTime);
cookie.setMaxAge(1*30*24*60*60);//保存一個(gè)月
//3.把cookie發(fā)送到瀏覽器保存
response.addCookie(cookie);
}
}
}
- 案例 : 查看用戶瀏覽器過(guò)的商品
Session技術(shù)
- 引入 :
- Cookie的局限:
1)Cookie只能存字符串類型宠哄。不能保存對(duì)象
2)只能存非中文壹将。
3)1個(gè)Cookie的容量不超過(guò)4KB。 - 如果要保存非字符串毛嫉,超過(guò)4kb內(nèi)容诽俯,只能使用session技術(shù)!3性痢暴区!
- Session特點(diǎn):會(huì)話數(shù)據(jù)保存在服務(wù)器端 (內(nèi)存中)
- Session技術(shù)核心(HttpSession類:用于保存會(huì)話數(shù)據(jù))
1)創(chuàng)建或得到session對(duì)象- HttpSession getSession()
- HttpSession getSession(boolean create)
2)設(shè)置session對(duì)象 - void setMaxInactiveInterval(int interval) : 設(shè)置session的有效時(shí)間
- void invalidate() : 銷毀session對(duì)象
- java.lang.String getId() : 得到session編號(hào)
3)保存會(huì)話數(shù)據(jù)到session對(duì)象 - void setAttribute(java.lang.String name, java.lang.Object value) : 保存數(shù)據(jù)
- java.lang.Object getAttribute(java.lang.String name) : 獲取數(shù)據(jù)
- void removeAttribute(java.lang.String name) : 清除數(shù)據(jù)
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* 保存會(huì)話數(shù)據(jù)到session域?qū)ο? */
public class SessionDemo1 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//1.創(chuàng)建session對(duì)象
HttpSession session = request.getSession();
/**
* 得到session編號(hào)
*/
System.out.println("id="+session.getId());
/**
* 修改session的有效時(shí)間
*/
//session.setMaxInactiveInterval(20);
/**
* 手動(dòng)發(fā)送一個(gè)硬盤(pán)保存的cookie給瀏覽器
*/
Cookie c = new Cookie("JSESSIONID",session.getId());
c.setMaxAge(60*60);
response.addCookie(c);
//2.保存會(huì)話數(shù)據(jù)
session.setAttribute("name", "rose");
}
}
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* 從session域?qū)ο笾腥〕鰰?huì)話數(shù)據(jù)
*/
public class SessionDemo2 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//1.得到session對(duì)象
HttpSession session = request.getSession(false);
if(session==null){
System.out.println("沒(méi)有找到對(duì)應(yīng)的sessino對(duì)象");
return;
}
/**
* 得到session編號(hào)
*/
System.out.println("id="+session.getId());
//2.取出數(shù)據(jù)
String name = (String)session.getAttribute("name");
System.out.println("name="+name);
}
}
- Session原理
- 服務(wù)器能夠識(shí)別不同的瀏覽者, 在哪個(gè)session域?qū)ο蟊4鏀?shù)據(jù)闯团,就必須從哪個(gè)域?qū)ο笕〕觯?
- 瀏覽器1:(給s1分配一個(gè)唯一的標(biāo)記:s001,把s001發(fā)送給瀏覽器)
- 瀏覽器1 的新窗口(帶著s001的標(biāo)記到服務(wù)器查詢,s001->s1,返回s1)
- 新的瀏覽器1:(沒(méi)有帶s001,不能返回s1)
- 瀏覽器2:(沒(méi)有帶s001,不能返回s1)
- 代碼解讀:HttpSession session = request.getSession();
1)第一次訪問(wèn): 創(chuàng)建session對(duì)象颜启,給session對(duì)象分配一個(gè)唯一的ID偷俭,叫JSESSIONID
2)把JSESSIONID作為Cookie的值發(fā)送給瀏覽器保存
3)第二次訪問(wèn)的時(shí)候,瀏覽器帶著JSESSIONID的cookie訪問(wèn)服務(wù)器
4)服務(wù)器得到JSESSIONID缰盏,在服務(wù)器的內(nèi)存中搜索是否存放對(duì)應(yīng)編號(hào)的session對(duì)象
5)如果找到對(duì)應(yīng)編號(hào)的session對(duì)象涌萤,直接返回該對(duì)象
6)如果找不到對(duì)應(yīng)編號(hào)的session對(duì)象,創(chuàng)建新的session對(duì)象口猜,繼續(xù)走1的流程
結(jié)論:通過(guò)JSESSION的cookie值在服務(wù)器找session對(duì)象负溪!
- Sesson細(xì)節(jié)
1)getId() : 得到session編號(hào)
2)兩個(gè)getSession方法:- getSession(true) / getSession() : 創(chuàng)建或得到session對(duì)象。沒(méi)有匹配的session編號(hào)济炎,自動(dòng)創(chuàng)建新的session對(duì)象
- getSession(false) : 得到session對(duì)象川抡。沒(méi)有匹配的session編號(hào),返回null
3)void setMaxInactiveInterval(int interval) : 設(shè)置session的有效時(shí)間 - session對(duì)象銷毀時(shí)間:
- 默認(rèn)情況30分服務(wù)器自動(dòng)回收
- 修改session回收時(shí)間
- 全局修改session有效時(shí)間: 在web.xml中修改
<session config><session timeout>1</session timeout></session config>
默認(rèn)是以分鐘為單位 - 手動(dòng)銷毀session對(duì)象 : void invalidate() ->銷毀session對(duì)象
4)如何避免瀏覽器的JSESSIONID的cookie隨著瀏覽器關(guān)閉而丟失的問(wèn)題
總結(jié):
1)會(huì)話管理 : 瀏覽器和服務(wù)器會(huì)話過(guò)程中的產(chǎn)生的會(huì)話數(shù)據(jù)的管理
2)Cookie技術(shù) :
- 創(chuàng)建 :
new Cookie("name","value")
- 添加 :
response.addCookie(coookie)
- 獲取 :
request.getCookies();
3)Session技術(shù) : - 創(chuàng)建 :
request.getSession();
- 添加 :
setAttrbute("name","會(huì)話數(shù)據(jù)");
- 獲取 :
getAttribute("會(huì)話數(shù)據(jù)");