Java Web之Cookie和session

Cookie

概述

HTTP協議是無狀態的,無狀態的意思是每次請求都是獨立的,它的執行情況和結果與前面的請求和之後的請求都無直接關係,它不會受前面的請求響應情況直接影響,也不會直接影響後面的請求響應情況。

一句有意思的話來描述就是人生只如初見,對服務器來說,每次請求都是全新的。

狀態可以理解爲客戶端和服務器在某次會話中產生的數據,那無狀態的就以爲這些數據不會被保留。會話中產生的數據又是我們需要保存的,也就是說要“保持狀態”。因此cookie就是在這樣一個場景下誕生。

Cookie對象(在客戶端,不是內置對象):Cookie對象是由 服務端生成的 ,再發送給客戶端保存。
相當於 本地緩存的作用: 客戶端(hello.mp4,zs/abc)->服務端(hello.mp4;zs/abc)
作用:提高訪問服務端的效率,但是安全性較差。

Cookie的本質

Cookie的本質是一個鍵值對 Cookie: name=value
Cookie也是一個JAVA類在這個包下→javax.servlet.http.Cookie
主要有以下方法:
public Cookie(String name,String value)
String getName():獲取name
String getValue():獲取value
void setMaxAge(int expiry);最大有效期 (秒)

Cookie的產生和使用過程

以一個能記住用戶名的登陸功能作爲例子:
先寫一個校驗登陸信息的頁面(check.jsp)↓

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<%
		request.setCharacterEncoding("utf-8");
		String name = request.getParameter("uname");
		String pwd = request.getParameter("upwd");
		if(name.equals("zs") && pwd.equals("abc")){
			Cookie cookie1 = new Cookie("name",name);
			Cookie cookie2 = new Cookie("pwd",pwd);
			//設定cookie的有效時間爲10秒
			cookie1.setMaxAge(10);
			response.addCookie(cookie1);
			response.addCookie(cookie2);
			response.sendRedirect("result.jsp");
		}else{
			out.print("登陸失敗用戶名或密碼有誤");
		}
	%>

</body>
</html>

再寫登陸成功後會轉跳到的頁面(result.jsp)↓

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
登陸成功!
</body>
</html>

現在寫一個登陸時的頁面(login.jsp),他會使用Cookie(如果有的話)↓

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	
	<%!
		//用於記錄服務器返回的Cookie裏面的uname值
		String uname;
	%>
	<% 
		boolean flag = false;//cookie默認失效
		//從request重獲取,一次會獲得所有的cookie
		Cookie[] cookies = request.getCookies();
			for(Cookie cookie:cookies){
			//如果能找到key爲name的cookie
				if(cookie.getName().equals("name")){
					uname = cookie.getValue();
					flag = true;
				}
			}
		if(!flag){
			out.print("Cookie 已失效");
		}else{
			out.print("Cookie:"+ uname );
		}
		
	%>
	
	<form action="check.jsp" method="post">
		<!-- uname不爲空時使用uname作爲用戶名的值 -->
		用戶名:<input type="text" name="uname" value="<%=uname==null?"":uname%>"/><br/>
		密碼:<input type="password" name="upwd"/>
		<input type="submit" value="登陸">
	</form>

</body>
</html>

測試

打開登陸頁面↓
在這裏插入圖片描述
輸入zs和abc↓
在這裏插入圖片描述
登陸成功↓
在這裏插入圖片描述
回到login.jsp↓發現用戶名自動保存了,說明cookie生效了(**PS:**有時候會因爲某些緩存的原因需要刷新幾次才能看到這個頁面)
在這裏插入圖片描述
10秒後刷新發現cookie已經失效了,但是由於瀏覽器的功能,用戶名還是被記錄了下來:
在這裏插入圖片描述

Cookie總結:

  1. 服務端準備Cookie的方法:
    Cookie cookie1 = new Cookie(“name1”,“zs”);
    response.addCookie(Cookie cookie)
  2. 服務器通過頁面跳轉(轉發,重定向)發送Cookie
  3. 使用Cookie實現 記住用戶名 功能
  4. 客戶端獲取cookie的方法: request.getCookies();此方法會一次性獲得所有從服務端發送過來的cookie,所以需要用一個Cookie[] (Cookie數組)接收
  5. 通過F12可以發現 除了自己設置的Cookie對象外,還有一個name爲 JSESSIONID的cookie(這個Cookie與在下面的session有緊密聯繫)
    在這裏插入圖片描述

session

客戶端第一次請求服務端時,(jsessionid-sessionid)服務端會產生一個session對象(用於保存該客戶的信息);
並且每個session對象 都會有一個唯一的 sessionId( 用於區分其他session);
服務端由會 產生一個cookie,並且 該cookie的name=JSESSIONID ,value=服務端sessionId的值;
然後 服務端會在 響應客戶端的同時 將該cookie發送給客戶端,至此 客戶端就有了 一個cookie(JSESSIONID);
因此,客戶端的cookie就可以和服務端的session一一對應(JSESSIONID - sessionID)

客戶端第二/n次請求服務端時:服務端會先用客戶端cookie種的JSESSIONID 去服務端的session中匹配sessionid,如果匹配成功(cookie jsessionid和sesion sessionid),說明此用戶 不是第一次訪問,無需登錄;

例子:
客戶端: 顧客 ->鑰匙(cookie和jsessionid)
服務端: 商場 ->存包櫃(session和sessionid)

顧客第一次存包:商場 判斷此人是 之前已經存過包(通過你手裏是否有鑰匙)。
如果是新顧客(沒鑰匙) ,分配一個鑰匙 給該顧客; 鑰匙 會和 櫃子 一一對應;

第二/n次 存包:商場 判斷此人是 之前已經存過包(通過你手裏是否有鑰匙)
如果是老顧客(有鑰匙),則不需要分配;該顧客手裏的鑰匙 會 和櫃子 自動一一對應。

代碼例子:CSDN:https://download.csdn.net/download/weixin_43217564/11592915
百度網盤:鏈接:https://pan.baidu.com/s/1HilWabj0uUjiCD6q6MPyww
提取碼:y9ka

總結

session:
a. session存儲在服務端
b. session是在 同一個用戶(客戶)請求時 共享
c. 實現機制:第一次客戶請求時 產生一個sessionid 並複製給 cookie的jsessionid 然後發給客戶端。最終 通過session的sessionid-cookie的jsessionid

session方法:
String getId() :獲取sessionId
boolean isNew() :判斷是否是 新用戶(第一次訪問)
void invalidate():使session失效 (退出登錄、註銷)

void setAttribute()
Object getAttribute();

void setMaxInactiveInterval(秒) :設置最大有效 非活動時間
int getMaxInactiveInterval():獲取最大有效 非活動時間

示例:
登錄

客戶端在第一次請求服務端時,如果服務端發現 此請求沒有 JSESSIONID,則會創建一個 name=JSESIONID的cookie 並返回給客戶端

Cookie:
a.不是內對對象,要使用必須new
b.但是,服務端會 自動生成一個(服務端自動new一個cookie) name=JSESIONID的cookie 並返回給客戶端

cookie和session的區別:

session cookie
保存的位置 服務端 客戶端
安全性 較安全 較不安全
保存的內容 Object String
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章