會話管理技術Cookie&Session
會話管理技術概述
1.什麼是會話
這裡的會話指的是web開發中的一次通話過程,當開啟瀏覽器,訪問網站地址後,會話開始,當關閉瀏覽器(或者到了過期時間),會話結束。
2.會話管理技術能做什麼
共享同一個客戶瀏覽器多個請求中資料,例如過濾。
客戶端會話管理技術 (Cookie)
1.什麼是Cookie?
它是客戶端瀏覽器的快取檔案,裡面記錄了客戶瀏覽器訪問網站的一些內容,它是http協議請求和響應訊息頭的一部分。
2.Cookie能做什麼?
能儲存客戶瀏覽器訪問網站的相關內容(需要伺服器開啟Cookie)。從而在每次訪問需要同一個內容時,先從本地快取獲取,使資源共享,並且提高效率。
3.Cookie中的屬性
name:必要屬性,cookie的名稱
value:必要屬性,cookie的值
path:cookie的路徑
domain:cookie的域名,相當於訪問的網站(localhost)
maxAge:cookie的生存時間(>0硬碟cookie;<0記憶體cookie;=0追殺cookie
version:cookie版本號(不重要)
comment:cookie的說明(不重要)
4.案例
儲存使用者名稱
package cn.itheima.username; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 登陸介面類 * @author LBK * */ public class UserSaveUI extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); String username=""; String ischk=""; Cookie cs[]=request.getCookies(); for(int i=0;cs!=null&&i<cs.length;i++){ if("userinfo".equals(cs[i].getName())){ username=cs[i].getValue(); ischk="checked"; } } //表單方式介面佈局 out.write("<form action='"+request.getContextPath()+"/LoginUserNameSave' method='post'>"); out.write("使用者名稱:<input type='text' name='username' value='"+username+"' /><br/>"); out.write("<input type='checkbox' name='remember' "+ischk+" />記住使用者名稱<br/> "); out.write("<input type='submit' value='登入' />"); out.write("</form>"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); } }
package cn.itheima.username; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 儲存cookie的類 * @author LBK * */ public class LoginUserNameSave extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); //獲取UI端傳送過來的請求 String username=request.getParameter("username"); String remember=request.getParameter("remember"); //判斷使用者名稱是否為空 if("".equals(username)||username==null){ out.write("使用者名稱不能為空,2秒後返回登陸頁"); response.setHeader("Refresh", "2;URL="+request.getContextPath()+"/UserSaveUI"); return; } //如果存在將username存入cookie Cookie cookie=new Cookie("userinfo",username); if(remember==null||"".equals(remember)){ cookie.setMaxAge(0); }else{ cookie.setMaxAge(Integer.MAX_VALUE); } //返回給客戶端cookie response.addCookie(cookie); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // response.setContentType("text/html"); // PrintWriter out = response.getWriter(); doGet(request, response); } }
服務端會話管理技術
1. 什麼是HttpSession
它是一個服務端會話物件,儲存使用者的會話資料.
2. HttpSession的生命週期
出生--活著--死亡
出生:呼叫getSession方法後會話開始
活著:只要沒有關閉會話或者呼叫立即消失的方法.或者伺服器意外,HttpSession一直存在
死亡:立即消失,到了過期時間,伺服器意外
3. 域物件(三缺一)
HttpSession:也是一個域物件,它比application域範圍小,比request域範圍大
4. 案例
防止重複提交
package cn.itheima.form;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.UUID;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionContext;
/**
* 介面類
* 生成介面,生成令牌
* @author LBK
*
*/
public class UI extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
//生成一個令牌
String token=UUID.randomUUID().toString();
//建立一個session 將UUID放到裡面
HttpSession s=request.getSession();
s.setAttribute("stoken", token);
//繪製介面
out.write("<form action='"+request.getContextPath()+"/Tran' method='post' >");
out.write("設定轉賬金額:<input type='text' name='money' /><br/>");
//新增一個隱藏域,存放令牌
out.write("<input type='hidden' name='ftoken' value='"+token+"' />");
out.write("<input type='submit' value='轉賬' />");
out.write("</form>");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
package cn.itheima.form;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* 根據得到的令牌判斷是否在進行重複提交操作
* @author LBK
*
*/
public class Tran extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
String money=request.getParameter("money");
String ftoken=request.getParameter("ftoken");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
HttpSession s=request.getSession();
String stoken=(String) s.getAttribute("stoken");
if(ftoken.equals(stoken)){
out.write("轉賬成功!"+money);
s.removeAttribute("stoken");
}else{
out.write("請不要重複提交!");
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
5. 使用者端禁用Cookie後會話資料的保持
方式一:使用文字提示.163郵箱就是使用的這種方式
方式二:URL重寫
解釋:當禁用了cookie之後,客戶端永遠都不會帶cookie到伺服器.
解決:我們自己給他戴上,把URL重寫.拼上一個JSESSIONID=session的ID.
使用的是response.encodeURL()方法
原來:http://localhost:8080/servletdemo/ServletDemo1
現在:http://localhost:8080/servletdemo/ServletDemo1;JSESSIONID=123
6. HttpSession物件的狀態
a.什麼是持久化
把長時間不用,但還不到過期時間的HttpSession進行序列化,寫到磁碟上.我們把HttpSession持久化也叫做鈍化.(與鈍化相反的是活化)
b.什麼時候使用持久化
第一種情況:當訪問量很大時,伺服器會根據getLastAccessTime來進行排序,對長時間不用,但是還沒到過期時間的HttpSession進行持久化.
第二種情況:當伺服器進行重啟的時候,為了保持客戶的HttpSession中的資料,也要對HttpSession進行持久化.