session

        在WEB開發中,服務器能夠爲每一個用戶瀏覽器建立一個會話對象(session對象),注意:一個瀏覽器獨佔一個session對象(默認狀況下)。所以,在須要保存用戶數據時,服務器程序能夠把用戶數據寫到用戶瀏覽器獨佔的session中,當用戶使用瀏覽器訪問其它程序時,其它程序能夠從用戶的session中取出該用戶的數據,爲用戶服務。html



Session和Cookie的主要區別

1. Cookie是把用戶的數據寫給用戶的瀏覽器。java

2. Session技術把用戶的數據寫到用戶獨佔的session中。
web

3. cookie是客戶端技術數據庫

1). 數據保存在客戶端,這個信息能夠保存很長時間瀏覽器

2). 數據隨時有可能被清空,因此cookie保存的數據是不太靠譜的安全

3). 數據被保存在了客戶端,隨時有可能被人看走,若是將一些敏感信息好比用戶名密碼等信息存在cookie中,可能有安全問題服務器

4. session是服務器端技術cookie

1). 數據保存在服務區端,相對來講比較穩定和安全session

2). 佔用服務器內存,因此通常存活的時間不會太長,超過超時時間就會被銷燬.咱們要根據服務器的壓力和session 的使用狀況合理設置session的超時時間,既能保證session的存活時間夠用,同時不用的session能夠及時銷燬減小對服務器內存的佔用.dom



Session 是一個域

 1. 做用範圍:當前會話範圍

 2. 生命週期:
        1) 當程序第一次調用到request.getSession()方法時說明客戶端明確的須要用到session此時建立出對應客戶端的Session對象.

        2) 當session超過30分鐘(能夠在web.xml中配置<session-config>設置該時間值)沒有人使用則認爲session超時銷燬這個session.

        3)  程序中明確的調用session.invalidate()方法能夠當即殺死session.

        4)  當服務器被非正常關閉時,隨着虛擬機的死亡而死亡.

        5)  *若是服務器是正常關閉,還未超時的session會被以文件的形式保存在服務器的work目錄下,這個過程叫作session的鈍化.下次再正常啓動服務器時,鈍化着的session會被恢復到內存中,這個過程叫作session的活化.

  3. 做用:在會話範圍內共享數據



session 的原理(request.getSession()方法內部執行)

1. 檢查請求中有沒有名字爲 jsessionid的cookie,若是有,則拿出值(值爲session 的惟一id)找到對應的session.

2. 若是沒有,則檢查請求的URL後有沒有以參數的名字爲jsessionid ,若是有則找到對應的Session。

3. 若是cookie中和url參數中都沒有找到,則認爲這個瀏覽器沒有對應的Session,建立一個Session而後再在響應中添加名字爲 jsessionid 的cookie,值就是這個Session 的id。



根據原理,實現多開同種瀏覽器共享session、關閉瀏覽器再打開不丟失session

       默認狀況下,JSESSIONID 的path爲當前web應用的名稱,而且沒有設置過MaxAge,是一個會話級別的cookie. 這意味着一旦關閉瀏覽器再新開瀏覽器時,因爲JSESSIONID丟失,會找不到以前的Session。另外同時打開多個IE瀏覽器也沒法共享同一session

     所以咱們能夠手動的發送名字爲 jsessionid 的cookie,名字和path設置的和自動發送時同樣,可是設置一下MaxAge,使瀏覽器除了在內存中保存JSESSIONID信息之外還在臨時文件夾中以文件的形式保存,這樣即便重開瀏覽器仍然可使用以前的session。

	/**
	 * 設置session ,自定義jsessionid 的cookie。 
	 * ① 防止瀏覽器關閉等狀況形成的session丟失
	 * ② 同時打開多個同種(IE)瀏覽器 ,共享session
	 * 
	 * @param strName
	 * @param strValue
	 * @param hour
	 *            有效小時數,若是此參數爲0,cookie在瀏覽器關閉的時候自動失效
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static void SetSesionCookie(HttpServletRequest request,
			HttpServletResponse response, String strName, String strValue,
			int hour) throws UnsupportedEncodingException {
		// String prod = request.getParameter(strName);
		// prod = new String(prod.getBytes("iso8859-1"), "utf-8");

		HttpSession session = request.getSession();
		// 自定義jsessionid 的cookie義
		Cookie jc = new Cookie("JSESSIONID", session.getId());
		jc.setPath(request.getContextPath());
		jc.setMaxAge(hour);
		response.addCookie(jc);

		session.setAttribute(strName, strValue);
	}



IE禁用Cookie後的session處理(URL重寫)

        若是瀏覽器禁用了Cookie,瀏覽器就沒有辦法JSESSIONID cookie,這樣就用不了Session了.

1). 咱們可使用URL重寫的機制,在全部的超連接後都以參數的形式拼接JSESSIONID信息,從而在點擊超連接時可使用URL參數的方式待會JSESSIONID,從而使用Session

2). 將URL進行重寫拼接上JSESSIONID的過程就叫作URL重寫

request.getSession() --在URL重寫以前必定要先建立出Session,纔有Session id,才能進行重寫

response.encodeURL()--- 通常的地址都用這個方法重寫

response.encodeRedirectURL() --- 若是地址是用來進行重定向的則使用這個方法

*url重寫的方法一旦發現瀏覽器帶回了任意cookie信息,則認爲客戶端沒有禁用cookie,就不會再進行重寫操做

<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://"
			+ request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
			
	request.getSession();
	String url1 = path + "/servlet/BuyServlet?prod=電視機";
	//encodeURL 方法,若是發現瀏覽器帶回了任意cookie信息,則認爲客戶端沒有禁用cookie,就不會再進行重寫操做,不然會重寫,
	//在url後面加jsessionid,改爲	path + "/servlet/BuyServlet;jessionid=ASDADKLADJFIOJQEWLADFAL?prod=電視機
	url1 = response.encodeURL(url1);
	String url2 = path + "/servlet/BuyServlet?prod=冰箱";
	url2 = response.encodeURL(url2);
	String url3 = path + "/servlet/PayServlet";
	url3 = response.encodeURL(url3);
%>

		<a href="<%=url1%>">電視機</a>
		<br />
		<a href="<%=url2%>">冰箱</a>
		<br />
		<a href="<%=url3%>">結帳</a>
		<br />



session案例-防止表單重複提交

1.  在頁面上生成一個隨機數的session,同時將值賦值隱藏控件,兩個值是相等的。

		<%
		  	Random r = new Random();
		  	int valinum = r.nextInt();
		  	session.setAttribute("valinum",valinum+"");
		%>
		<form
			action="${pageContext.request.contextPath }/servlet/ResubServlet"
			method="POST" onsubmit="return canSub()">
			用戶名:
			<input type="text" name="username" />
			<input type="hidden" name="valinum" value="<%=valinum %>" />
			<input type="submit" value="註冊" />
		</form>


2. 在後臺取出,隱藏控件中的值、session中的值,第一次提交後,移除session中的值,此時兩個值再也不相等了。

3. 若是是第二次提交,兩個值不相等,說明是重複提交。

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/html;charset=utf-8");
		request.setCharacterEncoding("utf-8");
		String username = request.getParameter("username");
		String hideVal = request.getParameter("valinum");
		String sessionVal = (String) request.getSession().getAttribute(
				"valinum");
		if (sessionVal != null && !"".equals(sessionVal)
				&& hideVal.equals(sessionVal)) {
			request.getSession().removeAttribute("valinum");
			System.out.println("向數據庫中註冊一次:" + username);
		} else {
			response.getWriter().write("from web:不要重複提交!!");
		}
	}





刪除獲取設置Session

	/**
	 * 設置session ,自定義jsessionid 的cookie。 
	 * ① 防止瀏覽器關閉等狀況形成的session丟失 
	 * ② 同時打開多個同種(IE)瀏覽器 ,共享session
	 * 
	 * @param strName
	 * @param strValue
	 * @param hour
	 *            有效小時數,若是此參數爲0,cookie在瀏覽器關閉的時候自動失效
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static void SetSesionCookie(HttpServletRequest request,
			HttpServletResponse response, String strName, String strValue,
			int hour) throws UnsupportedEncodingException {
		// String prod = request.getParameter(strName);
		// prod = new String(prod.getBytes("iso8859-1"), "utf-8");

		HttpSession session = request.getSession();
		// 自定義jsessionid 的cookie義
		Cookie jc = new Cookie("JSESSIONID", session.getId());
		jc.setPath(request.getContextPath());
		jc.setMaxAge(hour);
		response.addCookie(jc);

		session.setAttribute(strName, strValue);
	}

	/**
	 * 設置session
	 * 
	 * @param strName
	 * @param strValue
	 * @param hour
	 *            有效小時數,若是此參數爲0,cookie在瀏覽器關閉的時候自動失效
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static void SetSesion(HttpServletRequest request, String strName,
			String strValue) throws UnsupportedEncodingException {
		HttpSession session = request.getSession();
		session.setAttribute(strName, strValue);
	}

	/**
	 * 讀取session 若是爲空,返回null
	 * 
	 * @param strName
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static String GetSession(HttpServletRequest request,
			HttpServletResponse response, String strName)
			throws UnsupportedEncodingException {
		// 通知瀏覽器以UTF-8碼錶打開回送的數據
		response.setContentType("text/html;charset=utf-8");

		HttpSession session = request.getSession();
		// String prod = new String(prod.getBytes("iso8859-1"), "utf-8");
		String prod = (String) session.getAttribute(strName);
		return prod;
	}

	/**
	 * 刪除指定session
	 * 
	 * @param strName
	 * @return
	 */
	public static void DelSession(HttpServletRequest request, String strName) {
		if (request.getSession(false) != null
				&& request.getSession().getAttribute(strName) != null) {
			request.getSession().removeAttribute(strName);
			// request.getSession().invalidate();
		}
	}

	/**
	 * 刪除全部session
	 * 
	 * @return
	 */
	public static void DelAllSession(HttpServletRequest request) {
		if (request.getSession(false) != null) {
			request.getSession(false).invalidate();
		}
	}
相關文章
相關標籤/搜索