JavaWeb初級學習 之 會話控制&表單重複提交問題

一、會話控制


1.爲什麼會出現會話控制


HTTP協議的特點:

純文本
無狀態
瀏覽器不能區分多個請求是否來自同一個用戶
但是有時候我們需要讓瀏覽器知道多個請求來自同一個用戶,比如:網上購物。所以就出現了會話控制
會話控制涉及到兩種技術
Cookie
Session

2.Cookie

Cookie就是服務器發送給瀏覽器的用於區分不同用戶的一段信息

Cookie的運行機制
1)服務器創建一個Cookie對象
2)服務器將Cookie對象發送給瀏覽器
3)以後瀏覽器發請求就會攜帶着該Cookie對象
4)服務器根據Cookie對象來區分不同的用戶

創建Cookie對象
//1.創建Cookie,Cookie對象的名稱(key)不能使用中文
Cookie cookie = new Cookie("username", "sunwukong");
Cookie cookie2 = new Cookie("username2", "zhubajie");
//2.將Cookie對象發送給瀏覽器
response.addCookie(cookie);
response.addCookie(cookie2);

獲取Cookie對象
//1.獲取Cookie對象
Cookie[] cookies = request.getCookies();
//2.遍歷得到每一個Cookie對象
if(cookies != null){
	for (Cookie cookie : cookies) {
		//獲取Cookie對象的名稱
		String name = cookie.getName();
		System.out.println(name);
		//獲取Cookie對象的值
		String value = cookie.getValue();
		System.out.println(value);
	}
}

修改Cookie對象
//修改Cookie對象有以下兩種方式:
//方式一:創建一個同名的Cookie對象
//Cookie cookie = new Cookie("username", "meihouwang");
//response.addCookie(cookie);
//方式二:修改Cookie的value值
Cookie[] cookies = request.getCookies();
if(cookies != null){
	for (Cookie cookie : cookies) {
		String name = cookie.getName();
		if("username".equals(name)){
			cookie.setValue("qitiandasheng");
			//將修改之後的Cookie對象發送給瀏覽器
			response.addCookie(cookie);
		}
	}
}

持久化Cookie對象
//創建一個Cookie對象
Cookie cookie = new Cookie("user", "admin");
//持久化Cookie對象
/*
 * 通過setMaxAge(int age)方法來持久化Cookie對象
 * age > 0 :在age秒後Cookie對象失效
 * age = 0 :Cookie對象立即失效
 * age < 0 :會話級別的Cookie對象,默認
 */
//設置Cookie對象7天內有效
//cookie.setMaxAge(60*60*24*7);
cookie.setMaxAge(-9);
//將Cookie對象發送給瀏覽器
response.addCookie(cookie);

Cookie對象的有效路徑:
不是訪問任何路徑都會攜帶所有的Cookie對象
Cookie的有效路徑即訪問那些路徑時會攜帶該對象,默認的有效路徑是當前Web應用的根目錄,我們還可以通過setPath()方法設置Cookie對象的有效路徑
//創建一個Cookie對象
Cookie cookie = new Cookie("user2", "admin2");
//設置Cookie對象的有效路徑
//setPath()中的路徑由瀏覽器解析
cookie.setPath("/Web07_Cookie/hello");
response.addCookie(cookie);

Cookie對象的用途:
廣告推送
免登錄


Cookie的缺陷:
Cookie對象是明文的,不安全
不同的瀏覽器對Cookie對象的大小和個數有限制
Cookie對象過多耗費流量
所以就出現了Session

3.Session

Session即我們非常熟悉的HttpSession,用來保存用戶信息

Session的運行機制
1)在服務器端創建一個Session對象,該對象有一個全球唯一的ID
2)在服務器端創建Session對象的同時還會創建一個name爲一個固定值JSESSIONID的Cookie對象併發送給瀏覽器,而且這個特殊的Cookie對象的value值就是Session對象的ID
3)以後瀏覽器發送請求時會攜帶name爲JSESSIONID的Cookie對象,服務器會根據Cookie對象的value值來驗證是否有對應的Session對象
4)服務器根據name爲JSESSIONID的Cookie對象來區分不同的用戶

Session對象的創建
Session對象在Servlet中通過request獲取,只有獲取了Session對象纔會設置對應的name爲JSESSIONID的Cookie對象
//獲取Session對象
HttpSession session = request.getSession();
//獲取session對象的id
String id = session.getId();
System.out.println(id);

通過持久化JSESSIONID的Cookie對象來保持Session對象
當我們關閉瀏覽器時,由於Cookie默認是會話級別的,所以JSESSIONID對應的Cookie對象失效,再次打開瀏覽器時就不能找到之前創建的Session對象,我們可以通過將JSESSIONID的Cookie對象持久化的方法找到之前的Session對象
//獲取ookie對象
Cookie[] cookies = request.getCookies();
if(cookies != null){
	for (Cookie cookie : cookies) {
		//獲取cookie的name
		String name = cookie.getName();
		if("JSESSIONID".equals(name)){
			//持久化該Cookie對象
		        cookie.setMaxAge(60);
		        //發送給瀏覽器
		        response.addCookie(cookie);
		}
	}
}

設置Session對象的最大空閒時間
Session對象的默認最大空閒時間是30分鐘,我們還可以設置它的最大空閒時間
//獲取Session對象
HttpSession session = request.getSession();
//設置Session對象的最大空閒時間
/*
 * 可以通過setMaxInactiveInterval(int age)來設置Session對象的最大空閒時間
 * age > 0 : 在age秒後Session對象失效
 * age = 0 : Session對象立即失效
 * age < 0 : Session對象永遠不失效
 *
 */
session.setMaxInactiveInterval(-8);
//我們通常使用下面的方法設置Session對象立即失效
session.invalidate();

鈍化與活化:
鈍化:Session對象及session域中的屬性從內存中序列化到硬盤上的過程
活化:Session對象及session域中的屬性從硬盤上反序列化到內存中的過程
要保證Session域中的屬性可以被鈍化和活化Session域中的屬性必須實現Serializable接口

URL重寫
在瀏覽器禁用Cookie的情況下,每次發請求無法攜帶Cookie對象,就導致無法找到之前創建的Session對象,這種情況下就可以通過URL重寫將JSESSIONID通過參數的形式發送到服務器,從而找到對應的Session對象
URL重寫有以下方式
<%     
	//通過response的兩個方法
	String url = response.encodeURL(request.getContextPath()+"/login.jsp");
	String url2 = response.encodeRedirectURL(request.getContextPath()+"/login.jsp");
%>
<!-- 通過標籤 --> 
<c:url value="/login.jsp"></c:url>

二、表單的重複提交

同一個表單,同樣的內容向服務器提交多次

表單重複提交的危害:
增加服務器的壓力

數據庫中會保存很多垃圾數據


表單重複提交主要有以下三種情況:


1)在轉發的情況下:表單提交成功之後反覆刷新成功頁面

產生的原因:在轉發的情況下,地址欄沒有變化,刷新成功頁面相當於重複向form表單中的action屬性值重複提交請求
解決方案:使用重定向

2)在網速很慢的情況下:反覆點擊提交按鈕

產生的原因:提交按鈕可以被點擊多次
解決方案:讓提交按鈕只能點擊一次


3)表單提交成功之後,點擊返回(回退)按鈕,在不刷新頁面的情況下再一次提交表單

產生的原因:服務器會處理重複提交的請求
解決方案:使用token(記號)來判斷是否是重複提交的請求
使用token的流程
①在服務器端使用UUID生成一個全球唯一的字符串(token),然後將它放到session域中
②將全球唯一的token放到表單的隱藏域中,隨着表單一起提交到服務器
③在服務器端獲取表單隱藏域中的token,然後session域中的token進行對比,如果相等:正常處理請求,不相等:即爲重複提交請求。
④將session域中的token移除





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章