JavaWeb從入門到精通(四)-會話管理
1 課程回顧
Servlet程式設計
1)Servlet生命週期(重點)
構造方法:建立servlet物件。預設情況下,第一次訪問servlet物件時。只調用1次。
init方法(有參):建立完servlet物件後呼叫。只調用1次。
注意:會呼叫無參的init方法。
service方法: servlet提供服務的方法。每次發出請求呼叫。
注意: request物件 ,response物件
destroy方法: tomcat伺服器停止或web應用重新部署,servlet物件銷燬,destroy方法被呼叫。
2)ServletConfig物件
獲取servlet的初始化引數:
getInitParameter("name ");
getInitParameterNames();
3)ServletContext物件
得到web應用路徑:
context.getContextPath();
request.getContextPath(); 等價於上面的程式碼
得到web應用引數:
context.getInitParameter("name");
context.getInitParameterNames();
域物件:
context.setAttribute("name",Object):儲存資料
context.getAttribute("name") 得到資料
context.removeAttribue("name") 清除資料
轉發
context.getRequestDispatcher("路徑").forward(request,response);
request.getRequestDispacher("路徑").forward(request,response); 等價於上面的程式碼
得到web應用中的資原始檔
context.getRealPath("路徑")
context.getResourceAsStream("路徑");
路徑問題:
publicvoid doGet(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {
response.setContentType("text/html;charset=utf-8");
//目標資源: target.html
/**
* 思考: 目標資源是給誰使用的。
* 給伺服器使用的: / 表示在當前web應用的根目錄(webRoot下)
* 給瀏覽器使用的: / 表示在webapps的根目錄下
*/
//1.轉發(給伺服器使用)
request.getRequestDispatcher("/target.html").forward(request, response);
//2.請求重定向(給瀏覽器使用)
response.sendRedirect("/day11/target.html");
// 3.html頁面的超連線href
response.getWriter().write("<html><body><ahref='/day11/target.html'>超連結</a></body></html>");
// 4.html頁面中的form提交地址
response.getWriter().write("<html><body><formaction='/day11/target.html'><inputtype='submit'/></form></body></html>");
}
讀取web應用下的資原始檔(例如properties):
/**
* . 代表java命令執行目錄。java執行命令在哪裡??在tomcat/bin目錄下
* 結論:在web專案中, . 代表在tomcat/bin目錄下開始,所以不能使用這種相對路徑。
*/
//讀取檔案。在web專案下不要這樣讀取。因為.表示在tomcat/bin目錄下
/*Filefile = new File("./src/db.properties");
FileInputStreamin = new FileInputStream(file);*/
/**
* 使用web應用下載入資原始檔的方法
*/
/**
* 1. getRealPath讀取,返回資原始檔的絕對路徑
*/
/*Stringpath =this.getServletContext().getRealPath("/WEB-INF/classes/db.properties");
System.out.println(path);
Filefile = new File(path);
FileInputStreamin = new FileInputStream(file);*/
/**
* 2. getResourceAsStream() 得到資原始檔,返回的是輸入流
*/
InputStreamin =this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
Propertiesprop = new Properties();
//讀取資原始檔
prop.load(in);
Stringuser = prop.getProperty("user");
Stringpassword = prop.getProperty("password");
System.out.println("user="+user);
System.out.println("password="+password);
2. 會話管理入門
2.1 生活中會話
我:小張,你會跳小蘋果碼?
小張:會,怎麼了?
我:公司年會上要表演節目,你教教我把
小張:沒問題,一頓飯而已。
我: OK。
。。。。。。。。
在這次生活中的會話中產生通話記錄(會話資料)
2.2 軟體中的會話
一次會話:開啟瀏覽器 -> 訪問一些伺服器內容 -> 關閉瀏覽器
登入場景:
開啟瀏覽器 -> 瀏覽到登陸頁面 -> 輸入使用者名稱和密碼 -> 訪問到使用者主頁(顯示使用者名稱)
修改密碼(輸入原密碼)
修改收貨地址
.......
問題:在此處登入會話過程中產生的資料(使用者會話資料)如何儲存下來呢?
購物場景:
開啟瀏覽器 -> 瀏覽商品列表 -> 加入購物車(把商品資訊儲存下來) -> 關閉瀏覽器
開啟瀏覽器-> 直接進入購物車 -> 檢視到上次加入購物車的商品 -> 下訂單 -> 支付
問題:在購物會話過程中,如何儲存商品資訊??
會話管理:管理瀏覽器客戶端和伺服器端之間會話過程中產生的會話資料。
域物件: 實現資源之間的資料共享。
request域物件
context域物件
登入場景:
小張:輸入“張三” (儲存資料:context.setAttribute("name","張三")) -> 使用者主頁(顯示“張三”)
小李:輸入“李四”(儲存資料:context.setAttribute("name","李四")) -> 使用者主頁(顯示“李四”)
問題: context是所有使用者公有的資源!!!會覆蓋資料。
小張:輸入“張三”(儲存資料:request.setAttribute("name","張三"))- > 使用者主頁(顯示“張三”) 問題:一定要使用轉發技術來跳轉頁面!!!
解決辦法:可以使用session域物件來儲存會話資料!!!
2.3 會話技術
Cookie技術:會話資料儲存在瀏覽器客戶端。
Session技術:會話資料儲存在伺服器端。
3 Cooke技術
3.1特點
Cookie技術:會話資料儲存在瀏覽器客戶端。
3.2Cookie技術核心
Cookie類:用於儲存會話資料
1)構造Cookie物件
Cookie(java.lang.Stringname, java.lang.String value)
2)設定cookie
voidsetPath(java.lang.String uri) :設定cookie的有效訪問路徑
voidsetMaxAge(int expiry) : 設定cookie的有效時間
voidsetValue(java.lang.String newValue) :設定cookie的值
3)傳送cookie到瀏覽器端儲存
voidresponse.addCookie(Cookie cookie) : 傳送cookie
4)伺服器接收cookie
Cookie[]request.getCookies() : 接收cookie
3.3Cookie原理
1)伺服器建立cookie物件,把會話資料儲存到cookie物件中。
newCookie("name","value");
2) 伺服器傳送cookie資訊到瀏覽器
response.addCookie(cookie);
舉例: set-cookie:name=eric (隱藏傳送了一個set-cookie名稱的響應頭)
3)瀏覽器得到伺服器傳送的cookie,然後儲存在瀏覽器端。
4)瀏覽器在下次訪問伺服器時,會帶著cookie資訊
舉例: cookie: name=eric (隱藏帶著一個叫cookie名稱的請求頭)
5)伺服器接收到瀏覽器帶來的cookie資訊
request.getCookies();
3.4Cookie的細節
1)void setPath(java.lang.String uri) :設定cookie的有效訪問路徑。有效路徑指的是cookie的有效路徑儲存在哪裡,那麼瀏覽器在有效路徑下訪問伺服器時就會帶著cookie資訊,否則不帶cookie資訊。
2)void setMaxAge(int expiry) : 設定cookie的有效時間。
正整數:表示cookie資料儲存瀏覽器的快取目錄(硬碟中),數值表示儲存的時間。
負整數:表示cookie資料儲存瀏覽器的記憶體中。瀏覽器關閉cookie就丟失了!!
零:表示刪除同名的cookie資料
3)Cookie資料型別只能儲存非中文字串型別的。可以儲存多個cookie,但是瀏覽器一般只允許存放300個Cookie,每個站點最多存放20個Cookie,每個Cookie的大小限制為4KB。
3.5案例- 顯示使用者上次訪問的時間
3.6案例-檢視使用者瀏覽器過的商品
4 Session技術
4.1引入
Cookie的侷限:
1)Cookie只能存字串型別。不能儲存物件
2)只能存非中文。
3)1個Cookie的容量不超過4KB。
如果要儲存非字串,超過4kb內容,只能使用session技術!!!
Session特點:
會話資料儲存在伺服器端。(記憶體中)
4.2Session技術核心
HttpSession類:用於儲存會話資料
1)建立或得到session物件
HttpSession getSession()
HttpSession getSession(booleancreate)
2)設定session物件
void setMaxInactiveInterval(intinterval) :設定session的有效時間
void invalidate() :銷燬session物件
java.lang.String getId() :得到session編號
3)儲存會話資料到session物件
voidsetAttribute(java.lang.String name, java.lang.Object value) :儲存資料
java.lang.ObjectgetAttribute(java.lang.String name) :獲取資料
voidremoveAttribute(java.lang.String name) :清除資料
4.3Session原理
問題:伺服器能夠識別不同的瀏覽者!!!
現象:
前提: 在哪個session域物件儲存資料,就必須從哪個域物件取出!!!!
瀏覽器1:(給s1分配一個唯一的標記:s001,把s001傳送給瀏覽器)
1)建立session物件,儲存會話資料
HttpSessionsession = request.getSession(); --儲存會話資料 s1
瀏覽器1 的新視窗(帶著s001的標記到伺服器查詢,s001->s1,返回s1)
1)得到session物件的會話資料
HttpSession session = request.getSession(); --可以取出 s1
新的瀏覽器1:(沒有帶s001,不能返回s1)
1)得到session物件的會話資料
HttpSession session = request.getSession(); --不可以取出 s2
瀏覽器2:(沒有帶s001,不能返回s1)
1)得到session物件的會話資料
HttpSession session = request.getSession(); --不可以取出 s3
程式碼解讀:HttpSession session = request.getSession();
1)第一次訪問建立session物件,給session物件分配一個唯一的ID,叫JSESSIONID
newHttpSession();
2)把JSESSIONID作為Cookie的值傳送給瀏覽器儲存
Cookiecookie = new Cookie("JSESSIONID", sessionID);
response.addCookie(cookie);
3)第二次訪問的時候,瀏覽器帶著JSESSIONID的cookie訪問伺服器
4)伺服器得到JSESSIONID,在伺服器的記憶體中搜索是否存放對應編號的session物件。
if(找到){
returnmap.get(sessionID);
}
Map<String,HttpSession>]
<"s001",s1>
<"s001,"s2>
5)如果找到對應編號的session物件,直接返回該物件
6)如果找不到對應編號的session物件,建立新的session物件,繼續走1的流程
結論:通過JSESSION的cookie值在伺服器找session物件!!!!!
4.4Sesson細節
1)java.lang.String getId() :得到session編號
2)兩個getSession方法:
getSession(true)/ getSession() : 建立或得到session物件。沒有匹配的session編號,自動創 建新的session物件。
getSession(false): 得到session物件。沒有匹配的session編號,返回null
3)void setMaxInactiveInterval(int interval) : 設定session的有效時間
session物件銷燬時間:
3.1預設情況30分伺服器自動回收
3.2修改session回收時間
3.3全域性修改session有效時間
<!-- 修改session全域性有效時間:分鐘 --> <session-config> <session-timeout>1</session-timeout> </session-config> |
3.4.手動銷燬session物件
void invalidate() :銷燬session物件
4)如何避免瀏覽器的JSESSIONID的cookie隨著瀏覽器關閉而丟失的問題
/** * 手動傳送一個硬碟儲存的cookie給瀏覽器 */ Cookie c = new Cookie("JSESSIONID",session.getId()); c.setMaxAge(60*60); response.addCookie(c); |
總結:
1)會話管理:瀏覽器和伺服器會話過程中的產生的會話資料的管理。
2)Cookie技術:
newCookie("name","value")
response.addCookie(coookie)
request.getCookies()
3)Session技術
request.getSession();
setAttrbute("name","會話資料");
getAttribute("會話資料")