一、會話控制
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對象是明文的,不安全所以就出現了Session
不同的瀏覽器對Cookie對象的大小和個數有限制
Cookie對象過多耗費流量
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移除