WEB開發會話技術01 1.會話 Web開發中,用到的4種會話跟蹤技術 - 博客園 (cnblogs.com) 會話的基本介紹 什麼是會話? 會話可簡單理解為:用戶開一個瀏覽器,點擊多個超鏈接,訪問伺服器多個web資源,然後關閉瀏覽器,整個過程稱之為一個會話。 會話過程中要解決的一些問題: (1)每 ...
WEB開發會話技術01
1.會話
Web開發中,用到的4種會話跟蹤技術 - 博客園 (cnblogs.com)
- 會話的基本介紹
-
什麼是會話?
會話可簡單理解為:用戶開一個瀏覽器,點擊多個超鏈接,訪問伺服器多個web資源,然後關閉瀏覽器,整個過程稱之為一個會話。
-
會話過程中要解決的一些問題:
(1)每個用戶在使用瀏覽器與伺服器進行會話的過程中,不可避免各自會產生一些數據,伺服器要想辦法為 每個用戶保存這些數據
(2)例如多個用戶點擊超鏈接通過一個servlet各自購買了一個商品,伺服器應該想辦法把每一個用戶購買的 商品保存在各自的地方,以便於這些用戶點結賬servlet時,結賬servlet可以得到用戶各自購買的商品, 為用戶結賬。
- 會話的兩種技術
- Session
- Cookie
事實上,Session和Cookie往往連在一起用的
2.Cookie基本介紹和作用
2.1Cookie有什麼用
問題1:大家在訪問一個網站的時候,是否能看到提示你上次登錄網站的時間,要註意的是不同用戶的上次登錄時間肯定是不一樣的,這是怎麼實現的?
問題2:在訪問某個購物網站的時候,是否能看到提示你曾經瀏覽過的商品,不同的用戶瀏覽過的商品肯定是不一樣的,這又是怎麼實現的?
問題3:還有我們登錄某個網站的時候,往往都可以選擇保存登錄信息,不用重覆輸入登錄信息,這又是怎麼做到的?
-
解決之道-Cookie技術
Cookie是客戶端技術,伺服器把每個用戶的數據以cookie的形式寫給用戶各自的瀏覽器。當用戶使用瀏覽器再去訪問伺服器中的web資源時,就會帶著各自的數據去。這樣,web資源處理的就是用戶各自的數據了。
-
cookie可以用來做什麼?
-
保存上次登錄時間等信息
-
保存用戶名,密碼,在一定時間內不用重新登錄
-
網站的個性化,比如定製網站的服務,內容等
-
2.2Cookie介紹
通俗地說,就是當一個用戶通過HTTP協議訪問一個伺服器的時候,這個伺服器會將一些key/value鍵值對返回給客戶端瀏覽器,並給這些數據加上一些限制條件,在條件符合時這個用戶下次訪問這個伺服器的時候,數據又被完整地帶回給伺服器。
-
Cookie是伺服器在客戶端保存的用戶的信息,比如登錄名,瀏覽歷史等,就可以以cookie方式存儲
-
Cookie信息就像是小甜餅一樣,數據量並不大,服務端在需要的時候可以從客戶端/瀏覽器讀取(HTTP協議)
例如:如果請求的是某網站,就會到瀏覽器存儲的cookie裡面找該網站對應的cookie,然後通過http請求頭的Cookie欄位,將其發送給對應的網站伺服器
-
再次說明,cookie數據是保存在瀏覽器的
3.Cookie的基本使用
-
cookie有點像一張表(k-v),分兩列,一個是名字,一個是值,數據類型都是String
-
如果創建一個Cookie(由服務端創建)
Cookie cookie=new Cookie(String name,String val); cookie.setMaxAge();//保存時間
-
如何將一個Cookie添加到客戶端
response.addCookie(cookie);
-
如何讀取cookie(在服務端讀取到cookie信息)
request.getCookie();
4.Cookie底層實現機制
首先創建一個web工程,因為cookie是servlet的一部分,因此要引入servlet-api,然後配置Tomcat
4.1創建cookie
例子
在web項目中創建並配置servlet:
web.xml:
<servlet>
<servlet-name>CreatCookie</servlet-name>
<servlet-class>com.li.cookie.CreatCookie</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CreatCookie</servlet-name>
<url-pattern>/creatCookie</url-pattern>
</servlet-mapping>
CreatCookie:
package com.li.cookie;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;
/**
* 演示如何創建cookie並保存到瀏覽器
*/
public class CreatCookie extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("CreatCookie doPost被調用");
//1.創建一個Cookie對象
//name-value形式,其中name是唯一不可重覆的;value是cookie的值
//可以創建多個cookie對象
//這時cookie還在伺服器端
Cookie cookie = new Cookie("username", "olien");
response.setContentType("text/html;charset=utf-8");
//2.將cookie發送給瀏覽器,讓瀏覽器將該cookie保存起來
response.addCookie(cookie);
PrintWriter writer = response.getWriter();
writer.print("<h1>創建cookie成功</h1>");
writer.flush();
writer.close();
}
}
-
運行tomcat,在瀏覽器訪問該servlet資源:
-
打開瀏覽器控制台,可以在HTTP響應中看到伺服器發送的cookie:
-
在控制台存儲處也可以看到該cookie:
4.2讀取cookie
如果瀏覽器保存了某一個網站的cookie信息後,當它發送請求給網站伺服器時,會自動地帶上跟這個伺服器關聯的cookie
例子
web.xml:
<servlet>
<servlet-name>ReadCookies</servlet-name>
<servlet-class>com.li.cookie.ReadCookies</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ReadCookies</servlet-name>
<url-pattern>/readCookies</url-pattern>
</servlet-mapping>
ReadCookies:
package com.li.cookie;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;
/**
* 讀取瀏覽器發來的cookie信息[基於http協議]
*/
public class ReadCookies extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("ReadCookies doPost被調用");
//1.通過request對象讀取cookie信息
Cookie[] cookies = request.getCookies();
//2.遍歷一下cookie
if (cookies != null && cookies.length != 0) {
for (Cookie cookie : cookies) {
System.out.println("cookie name= " + cookie.getName()
+ " value= " + cookie.getValue());
}
}
//3.給瀏覽器返回信息
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.print("<h1>讀取cookie信息成功</h1>");
writer.flush();
writer.close();
}
}
-
redeployTomcat,在瀏覽器訪問該servlet,輸出如下:
-
使用瀏覽器抓包,可以看到瀏覽器發送的http請求中帶有和當前伺服器關聯的cookie:
-
伺服器後臺輸出:
4.3JSESSIONID說明
有如下的情況:
A瀏覽器和其他瀏覽器都發送了請求給伺服器,伺服器分別創建了不同的cookie給這些瀏覽器,要求它們進行保存。當A瀏覽器帶上cookie信息發送給伺服器的時候,伺服器怎麼在許多會話中區分這次會話是跟A瀏覽器關聯的,還是跟其他不同的瀏覽器關聯的呢?
答案是用 jsessionid。不同的會話,jsessionid不同
驗證:不同的會話,jsessionid不同
-
第一次訪問Tomcat首頁: JSESSIONID=7F9AC09830943EEB6C58285812E5DE1C
-
關閉瀏覽器後重新打開再訪問:JSESSIONID=1231B81D45B63812FCF682FD5761AA30
如果重新打開瀏覽器發現jsession還是同一個,可能是瀏覽器緩存問題
5.Cookie應用實例
5.1讀取指定的cookie
需求:在伺服器端如何讀取到指定的cookie
(1)給定cookie的name,返回該cookie的值
(2)如果不存在該cookie,則返回null
例子
web.xml:
<servlet>
<servlet-name>ReadCookieByNameServlet</servlet-name>
<servlet-class>com.li.cookie.ReadCookieByNameServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ReadCookieByNameServlet</servlet-name>
<url-pattern>/readCookieByName</url-pattern>
</servlet-mapping>
修改CreatCookie:
package com.li.cookie;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;
/**
* 演示如何創建cookie並保存到瀏覽器
*/
public class CreatCookie extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("CreatCookie doPost被調用");
//1.創建一個Cookie對象
//name-value形式,其中name是唯一不可重覆的;value是cookie的值
//可以創建多個cookie對象
//這時cookie還在伺服器端
Cookie cookie = new Cookie("username", "jack");
Cookie cookie2 = new Cookie("email", "[email protected]");
response.setContentType("text/html;charset=utf-8");
//2.將cookie發送給瀏覽器,讓瀏覽器將該cookie保存起來
response.addCookie(cookie);
response.addCookie(cookie2);
PrintWriter writer = response.getWriter();
writer.print("<h1>創建cookie成功</h1>");
writer.flush();
writer.close();
}
}
ReadCookieByNameServlet:
package com.li.cookie;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;
public class ReadCookieByNameServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//System.out.println("ReadCookieByNameServlet doPost..");
//得到指定的cookie的值
//1.首先得到瀏覽器攜帶的所有cookies
Cookie[] cookies = request.getCookies();
//2.使用工具類來獲取指定的cookie
Cookie emailCookie = CookieUtils.readCookieByName("email", cookies);
if (null != emailCookie) {
System.out.println("得到emailCookie name=" + emailCookie.getName()
+ " value=" + emailCookie.getValue());
} else {
System.out.println("沒有這個cookie");
}
//3.給瀏覽器返回信息
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.print("<h1>完成讀取cookie的任務..</h1>");
writer.flush();
writer.close();
}
}
工具類CookieUtils:
package com.li.cookie;
import javax.servlet.http.Cookie;
public class CookieUtils {
//編寫一個方法,返回指定名字的cookie值
public static Cookie readCookieByName(String name, Cookie[] cookies) {
//判斷傳入的參數是否正確
if (name == null || "".equals(name) || cookies == null || cookies.length == 0) {
return null;
}
//否則,就遍歷cookies
for (Cookie cookie : cookies) {
if (name.equals(cookie.getName())) {
return cookie;
}
}
return null;
}
}
-
redeployTomcat,在瀏覽器中先訪問creatCookie資源(創建cookie)
-
再訪問readCookieByName資源:
-
伺服器後臺輸出:
5.2修改cookie
需求:演示如何修改cookie
5.2.1方式一
- 先找到需要修改的Cookie對象
- 調用setValue()方法賦予其新的Cookie值
- 調用response.addCookie()通知客戶端保存修改
例子
(1)給定一個cookie的name,找到該cookie,如果有,則修改該cookie的值為xxx
(2)如果找不到該cookie,則提示沒有該cookie
CookieUtils不變。
UpdateCookie:
package com.li.cookie;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(urlPatterns = {"/updateCookie"})
public class UpdateCookie extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("updateCookie doPost被調用...");
/**
* 需求:演示如何修改cookie
* (1)給定一個cookie的name,找到該cookie,如果有,則修改該cookie的值為xxx
* (2)如果找不到該cookie,則提示沒有該cookie
*/
//1.根據name去查找cookie
String cookieName = "email";
Cookie[] cookies = request.getCookies();
Cookie cookie = CookieUtils.readCookieByName(cookieName, cookies);
if (cookie == null) {//在該瀏覽器沒有email cookie
System.out.println("當前訪問服務端的瀏覽器沒有該cookie");
} else {
cookie.setValue("[email protected]");
}
//2.遍歷一下,看看有沒有變化
System.out.println("=====修改後的cookie信息=====");
for (Cookie cookie1 : cookies) {
System.out.println("cookie name=" + cookie1.getName()
+ " value=" + cookie1.getValue());
}
//3.給瀏覽器返回修改後的cookies
if (cookie != null) {
response.addCookie(cookie);
}
//4.給瀏覽器返回信息提示
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.print("<h1>完成修改cookie的任務</h1>");
writer.flush();
writer.close();
}
}
-
修改前瀏覽器對應的cookie如下:
-
redeployTomcat,在瀏覽器訪問updateCookie資源後,cookie的值改變了:
-
伺服器後臺輸出:
5.2.2方式二
創建一個同名的cookie發送給瀏覽器,相當於覆蓋原來的cookie的值
Cookie cookie = new Cookie("key1","value1");
response.addCookie(cookie);//底層http響應包的set-cookie:xxx相應變化
6.Cookie的生命周期
預設情況下,Cookie只在瀏覽器的記憶體中存活,也就是說,當你關閉瀏覽器後,Cookie就會消失。但是也可以通過方法設置cookie的生存時間。
cookie的生命周期指的是如何管理cookie,什麼時候cookie被銷毀。
- setMaxAge(int expiry):設置 cookie 的最大生存時間,以秒為單位
- 整數:表示在指定的秒數後過期
- 負數:表示瀏覽器關閉,cookie就會被刪除(預設值是-1)
- 0,表示馬上刪除cookie
例子1:指定參數為整數
CookieLive:
package com.li.cookie;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(urlPatterns = {"/CookieLive"})
public class CookieLive extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("CookieLive doPost被調用...");
//創建一個cookie,生命周期為 60s
Cookie cookie = new Cookie("job", "java");
//1.從創建改cookie開始計時,60秒後就無效
//2.由瀏覽器來根據創建的時間來開始計時,到時間後就認為該cookie無效
//3.如果該cookie無效了,那麼瀏覽器在發出HTTP請求時,就不會帶上該cookie
cookie.setMaxAge(60);
//將cookie保存到瀏覽器
response.addCookie(cookie);
//給瀏覽器返回信息
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.print("<h1>設置cookie生命周期成功</h1>");
writer.flush();
writer.close();
}
}
-
在瀏覽器中訪問該servlet:
、
-
可以看到該cookie的創建時間是 "Sun, 20 Nov 2022 14:15:39 GMT"
真實時間為上述時間再加八小時
-
超過60s後,再去訪問Tomcat伺服器:
代碼見4.2
在瀏覽器發送的HTTP請求中的Cookie欄位已經沒有了設置的cookie:
說明:由瀏覽器來根據創建的時間來開始計時,到時間後就認為該cookie無效。如果該cookie無效了,那麼瀏覽器在發出HTTP請求時,就不會帶上該cookie。
但是此時cookie沒有被刪除,在關閉瀏覽器的時候才會被刪除。
例子2:演示刪除cookie
刪除下圖名為email的cookie