1. 程式人生 > >會話管理技術Cookie&Session

會話管理技術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進行持久化.