橫軸射擊遊戲《Spectacular Sparky》面向PC/NS公佈
會話簡介
在計算機領域中,是存在會話的,客戶端與伺服器之間的一次通話就稱為會話。當開啟瀏覽器訪問一個地址請求成功後就意味著開啟了一個新的會話,會話期間可以多次訪問站點內的其他資源,這樣實際都是在一個會話中操作,直到瀏覽器關閉,表示此次會話結束。
會話是一個客戶與伺服器之間的不中斷的請求響應序列。
會話技術分類
- 客戶端會話:Cookie
- 伺服器會話:Session
會話作用
因為HTTP協議是無狀態的,所以很顯然伺服器不可能知道我們已經在上一次的HTTP請求中通過了驗證。當然,最簡單的解決方案就是所有的請求裡面都帶上使用者名稱和密碼,這樣雖然可行,但大大加重了伺服器的負擔(對於每個request都需要到資料庫驗證),也大大降低了使用者體驗(每個頁面都需要重新輸入使用者名稱密碼,每個頁面都帶有登入表單)。既然直接在請求中帶上使用者名稱與密碼不可行,那麼就只有在伺服器或客戶端儲存一些類似的可以代表身份的資訊了,所以就有了cookie與session,cookie和session用來跟蹤使用者的整個會話。
客戶端會話cookie
理解
- 在程式中,會話跟蹤是很重要的事情。理論上,一個使用者的所有請求操作都應該屬於同一個會話,而另一個使用者的所有請求操作則應該屬於另一個會話,二者不能混淆。例如,使用者A在超市購買的任何商品都應該放在A的購物車內,不論是使用者A什麼時間購買的,這都是屬於同一個會話的,不能放入使用者B或使用者C的購物車內,這不屬於同一個會話。
- 而Web應用程式是使用HTTP協議傳輸資料的。HTTP協議是無狀態的協議。一旦資料交換完畢,客戶端與伺服器端的連線就會關閉,再次交換資料需要建立新的連線。這就意味著伺服器無法從連線上跟蹤會話。即使用者A購買了一件商品放入購物車內,當再次購買商品時伺服器已經無法判斷該購買行為是屬於使用者A的會話還是使用者B的會話了。要跟蹤該會話,必須引入一種機制。Cookie就是這樣的一種機制。它可以彌補HTTP協議無狀態的不足。在Session出現之前,基本上所有的網站都採用Cookie來跟蹤會話。
原理
- Cookie是解決HTTP無狀態性的有效手段,伺服器可以設定或讀取Cookie中所包含的資訊。當用戶登入後,伺服器會發送包含登入憑據的Cookie到使用者瀏覽器客戶端,而瀏覽器對該Cookie儲存在硬碟C:\Users\使用者名稱\AppData\Local\Google\Chrome\User Data\Default)。使用者再次訪問該網站時,瀏覽器會發送該Cookie到伺服器,伺服器對該憑據進行驗證,合法時使使用者不必輸入使用者名稱和密碼就可以直接登入。
- 本質上講,Cookie是一段文字資訊。客戶端請求伺服器時,如果伺服器需要記錄使用者狀態,就在響應使用者請求時傳送一段Cookie資訊。客戶端瀏覽器儲存該Cookie資訊,當用戶再次訪問該網站時,瀏覽器會把Cookie做為請求資訊的一部分提交給伺服器。伺服器檢查Cookie內容,以此來判斷使用者狀態,伺服器還會對Cookie資訊進行維護,必要時會對Cookie內容進行修改。
總結
- 當從瀏覽器傳送請求到伺服器後,servlet建立cookie,儲存少量資料,傳送瀏覽器
- 瀏覽器獲得伺服器傳送的cookie資料,將自動的儲存到瀏覽器端
- 下次訪問時,瀏覽器將自動攜帶cookie資料傳送給伺服器。
語法
-
建立cookie:new Cookie(str,str)
-
將cookie響應給瀏覽器:addCookie(cookie)
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.net.URLEncoder; /** * @author: ChengLong * @version: 11.0.2 * @datetime: 2021/8/19 9:45 */ /* * 建立cookie * 第一次訪問建立cookie,在響應頭中 * 再次請求在請求頭中 * * */ @WebServlet("/c1") public class Cookie_Demo01 extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //建立cookie URLEncoder.encode 編碼 Cookie c = new Cookie("msg", URLEncoder.encode("少壯不努力,老大徒傷悲","utf-8")); //允許tomcat下所有專案都攜帶 c.setPath("/"); //將cookie響應會瀏覽器 resp.addCookie(c); } }
-
獲取瀏覽器攜帶的所有的cookie:Cookies[] getCookies()
-
返回cookie鍵:String getName()
-
返回cookie值:String getValue()
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.net.URLDecoder; import java.net.URLEncoder; /** * @author: ChengLong * @version: 11.0.2 * @datetime: 2021/8/19 10:14 */ /* * req.getCookies(); 獲取瀏覽器攜帶的所有的cookie * * cookie.getName() 返回cookie鍵 * cookie.getValue()返回cookie值 * */ @WebServlet("/c2") public class Cookie_Demo02 extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //獲取瀏覽器攜帶的所有的cookie URLDecoder.decode 解碼 Cookie[] cookies = req.getCookies(); if (cookies != null){ for (Cookie cookie : cookies) { System.out.println(cookie.getName()+"\t"+ URLDecoder.decode(cookie.getValue(),"utf-8")); } } } }
-
瀏覽器只會攜帶本專案的所有cookie到達伺服器
setPath(request.getContextPath()) 預設是當前專案
/:部署在當前伺服器下所有的專案都攜帶 -
設定最大存活時間 預設是瀏覽器關閉銷燬
setMaxAge(秒)import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.net.URLEncoder; /** * @author: ChengLong * @version: 11.0.2 * @datetime: 2021/8/19 10:26 */ /* *建立cookie帶生存時間的cookie * */ @WebServlet("/c3") public class Cookie_Demo03 extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //建立cookie URLEncoder.encode 編碼 Cookie c = new Cookie("msg", URLEncoder.encode("書山有路勤為徑,學海無涯苦作舟","utf-8")); //設定cookie存活時間 一小時 c.setMaxAge(60*60); //將cookie響應會瀏覽器 resp.addCookie(c); } }
清空持久化cookie
特點
- Cookie中只能以鍵值對的形式儲存字串型別的資料
- Cookie中儲存的資料有大小限制,一般不超過4kb
- Cookie是儲存在客戶端的,安全性較差
- Cookie預設有效期是瀏覽器關閉即銷燬,若持久化儲存Cookie物件,要設定有效期
使用場景
- 記住使用者名稱
- 歷史記錄
伺服器端會話session
理解
- Session是伺服器提供的一個會話物件,是第二大作用域物件。建立之後這個Session是儲存到伺服器中的。但Session的使用需要和瀏覽器建立關聯(session底層是基於cookie進行實現的),這個關聯與Cookie有關,其中每一個Session物件都會對應一個sessionId,這個sessionId就被儲存在Cookie中。
原理
- 當用戶第一次請求伺服器儲存資料的時候伺服器會為每一個使用者都建立一個session物件來去儲存使用者私有的資料,每一個session都有一個唯一的JSESSIONID。這個id儲存在每一個使用者的瀏覽器上,當用戶再次訪問伺服器的時候就會攜帶該使用者JSESSIONID去服務端找到與之對應的session物件
使用
-
獲取session物件:HttpSession session = request.getSession();
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; /** * @author: ChengLong * @version: 11.0.2 * @datetime: 2021/8/19 14:07 */ /* * api * request * HttpSession getSession() 獲取|建立一個session * */ @WebServlet("/s1") public class Session_Demo01 extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //獲取|建立一個session HttpSession session = req.getSession(); session.setAttribute("msg","我是大帥哥"); } }
-
儲存資料到session中:session.setAttribute(String 繫結名,Object 繫結值)
-
獲取session資料:session.getAttribute("繫結名")
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; /** * @author: ChengLong * @version: 11.0.2 * @datetime: 2021/8/19 14:07 */ /* * api * request * HttpSession getSession() 獲取|建立一個session * */ @WebServlet("/s2") public class Session_Demo02 extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //獲取|建立一個session HttpSession session = req.getSession(); Object msg = session.getAttribute("msg"); System.out.println(msg); } }
-
銷燬session物件:session.invalidate();
特點
- 儲存在伺服器端
- 預設儲存30分鐘
- Session做第二大域物件,在一個會話範圍內的資料是科共享的
- Session儲存的資料可以是任意型別
假死現象
-
瀏覽器關閉伺服器中的session找不到了造成session假死現象、但是它並不意味著session銷燬、因為session本身是在伺服器儲存著、只不過瀏覽器的cookie中儲存的JSESSION丟失了,造成無法匹配到伺服器中session。
-
伺服器關閉session也不會消失 因為session有預設存活時間30分鐘。當未到達30分鐘伺服器突然宕機,此時tomcat在6.x版本後引入自動備份機制。伺服器停止此時伺服器會將session中的內容序列化(鈍化)到硬碟上、當伺服器再次啟動時候就會從硬碟上讀取反序列化(活化)session內容到記憶體中。
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.*; import java.io.IOException; /** * @author: ChengLong * @version: 11.0.2 * @datetime: 2021/8/19 14:07 */ /* * session 持久化 * 就是將cookie進行持久化,讓瀏覽器關閉的時候不丟失JSESSIONID * */ @WebServlet("/s3") public class Session_Demo03 extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //獲取|建立一個session HttpSession session = req.getSession(); //設定cookie裡儲存sessionid Cookie c = new Cookie("JSESSIONID", session.getId()); //設定cookie最大保留時間 c.setMaxAge(60*30); //將cookie響應瀏覽器 resp.addCookie(c); session.setAttribute("msg","大家都是大帥哥"); } }
使用場景
- 使用者登入時安全校驗
- 購物車
Cookie和Session的區別
資料儲存位置上
- cookie資料儲存在瀏覽器
session資料儲存在伺服器
安全性
- cookie不太安全
session比較安全
儲存資料大小
- cookie最大隻允許儲存4kb
session儲存資料無限制
資料型別
- cookie鍵和值都是字串
session鍵是字串值可以是任意型別