JSP/Servlet會話管理機制
(一)知識概念
在Web服務器端編程中,會話狀態管理是一個經常必須考慮的重要問題。根據設計,HTTP是一種無狀態的協議。它意味著Web應用并不了解有關同一用戶以前請求的信息。
JSP有四個會話機制。Request,Session,Cookie,Application分別可以存儲不同范圍的值。
l Request
l Session
l Cookie
l Application
1.Request
(1)request.getParameter() 和request.getAttribute() 區別
1. request.getParameter()取得是通過容器的實現來取得通過類似post,get等方式傳入的數據,request.setAttribute()和getAttribute()只是在web容器內部流轉,僅僅是請求處理階段。
2. request.getParameter()方法傳遞的數據,會從Web客戶端傳到Web服務器端,代表HTTP請求數據。request.getParameter()方法返回String類型的數據。
(2)request.getAttribute()與request.setAttribute()
request.getAttribute("nameOfObj")可得到JSP頁面一表單中控件的Value。其實表單控件中的Object的 name與value是存放在一個哈希表中的,所以在這里給出Object的name會到哈希表中找出對應它的value。
而不同頁面間傳值使用request.setAttribute(position, nameOfObj)時,只會從a.JSP到b.JSP一次傳遞,之后這個request就會失去它的作用范圍,再傳就要再設一個 request.setAttribute()。而使用session.setAttribute()會在一個過程中始終保有這個值。
(3)request.getParameter() 和request.getParameterValues()
request.getParameterValues(String name)返回數組String[],用于獲得如checkbox類(名字相同,但值有多個)的數據。
request.getParameter(String name)返回String,用于獲得相應名的數據,如果有重復的名,則返回第一個的值。
(4)其它
JavaScript與JSP中不能相互傳值,因為JavaScript運行在客戶端,而JSP運行在服務器端。若想使它們之間可以相互傳遞參數,可以在JSP中設置一個hidden控件,用它的value結合上面所說的用法來傳遞所需的數值。
2.session、cookie、application
session、cookie、application是JSP中 的重要對象,這些對象和程序語言中的全局變量有些相似。在使用程序語言設計軟件程序時,不同的程序文件之間需要傳遞或共享某些數據,這就需要全局變量(也 叫公用變量)。在一個站點內,有眾多的動態網頁,每個網頁就相當于一個獨立的程序文件,他們之間的數據傳遞和數據共享就依賴于session等這些對象。但他們的應用不同于程序語言。存在的位置和使用的方法都和網絡環境有著密切聯系。這些對象一但被創建,session、application存在于JSP服務器上,cookie存在于客戶機上。session、cookie在使用時,能區分不同的用戶,會為不同IP地址的用戶,創建單獨的session或cookie。而application應用時是針對所有用戶的。下圖是表示他們之間區別和關系的示意圖:
這些對象在使用時,先要創建(定義),然后將需要的數據寫入。到了其他的動態網頁中,就可以提取。設定或改變對象的屬性參數,能夠能夠改變他存在的形式和壽命,還可以在不需要時,將其刪除。
(二)應用舉例
1.客戶端向服務器
(1)get方式
<a href="xx.jsp?id=<%=id%>"></a>
<a href="xx.jsp?id=2"></a>
<script language='javascript'>
var val = document.getElementById('varSort').value;
window.location.href = "index.jsp?param=" + val;
</script>
(2)post方式
<form action="xx.jsp?act=3" method="post" enctype="multipart/form-data" name="upfile" id="upfile">
<input type="hidden" name="id" value="<%=id%>">
<input type="text" name="root">
</form>
2.服務器端
response.sendRedirect做轉向的原理,它其實是向瀏覽器發送一個特殊的Header,然后由瀏覽器來做轉向,轉到指定的頁面,所以用sendRedirect時,瀏覽器的地址欄上可以看到地址的變化。
用<jsp:forward page=""/>則不同,它是直接在server做的,瀏覽器并不知道,也不和瀏覽器打交道,這從瀏覽器的地址并不變化可以看出。
(1)跳轉之后 地址欄變為xx.jsp【客戶端跳轉】
response.setHeader("refresh", "5", "xx.jsp");
response.sendRedirect("xx.jsp?=" + id);
(2)跳轉以后地址欄不變【服務器端跳轉】
<jsp:forward page="xx.jsp">
<jsp:param name="g" value="<%=name%>"/>
</jsp:forward>
<jsp:include flush="true" page="xx.jsp">
<jsp:param name="t" value="<%=request.getParameter("id")>">
</jsp>
(3)session
session.setAttrubute("name", name)
l session是在多個頁面之中有效,而不是只在兩個頁面中有效,直到關閉瀏覽器才失效。
l session銷毀的三個條件
n 服務器停
n 設置的時間到
n 手動關閉
l 打開多個瀏覽器和打開多個標簽頁之間的區別。
(4)Cookie
寫入cookie
Cookie user=new Cookie("user", username);
Cookie pass=new Cookie("pass", password);
response.addCookie(user);
response.addCookie(pass);
從cookie中提取數據
Cookie[] allcookie = request.getCookies();
name2=allcookie[0].getValue();
mima2=allcookie[1].getValue();
(5)application
數據寫入application
application.setAttribute("dirimg", myimg);
從application中讀取數據
tp = (String)application.getAttribute("dirimg");
3.javaBean
通過表單提交過來的值,經過Bean自動的將字符串處理為相應的數據類型,然后自動的與javaBean中的屬性相同的名稱進行匹配。
<jsp:useBean id="testBean" class="swing.useBean" scope="session"/>
<jsp:setProperty name="testBean" property="*"/>
</jsp:useBean>
bookName:<%=testBean.getBookName()%>
bookCompany:<%=testBean.getBookCompany()%>
4.jsp與javascript中文cookie交互
jsp 寫入中文Cookie
<%@ page contentType="text/html;charset=utf-8" pageEncoding="UTF-8"%>
<%@ page import="java.net.*"%>
<%
String usr = "中文cookie測試";
Cookie cookie = new Cookie("usr", URLEncoder.encode(usr, "UTF-8"));
cookie.setMaxAge(31536000);
cookie.setPath("/");
response.addCookie(cookie);
%>
javascript 讀取中文cookie
<script language="javascript">
function readCnCookie(name) {
var strReturn = null;
var tmp, reg=new RegExp("(^| )" + name + "=\"*([^;|^\"]*)(|;|$)", "gi");
if(tmp=reg.exec(document.cookie))
strReturn = decodeURIComponent(tmp[2]);
return strReturn;
}
alert(readCnCookie("usr"));
</script>
同樣, 不管有什么服務端語言, 寫入cookie 時 把中文使用 URLEncode 就可以和js交互了
在其它的語言環境下實現 new Cookie("usr",URLEncoder.encode(usr,"UTF-8"))方法:
l ASP:Server.URLEncode(string);
l PHP:urlencode($string);
n 如果編碼不對, 記得用 iconv 轉換一下
n 例: gb2312轉utf-8 iconv("GB2312", "UTF-8", $string);
l ASP.NET:
n System.Web.HttpUtility.UrlEncode(string);
n System.Web.HttpUtility.UrlEncode(string, "UTF-8");
5.理解HTTP session原理及應用
全文見:http://www.cnblogs.com/athrun/archive/2008/11/26/1341442.html
session機制是一種服務器端的機制,服務器使用一種類似于散列表的結構(也可能就是使用散列表)來保存信息。
當程序需要為某個客戶端的請求創建一個session的時候,服務器首先檢查這個客戶端的請求里是否已包含了一個session標識 - 稱為 session id,如果已包含一個session id則說明以前已經為此客戶端創建過session,服務器就按照session id把這個 session檢索出來使用(如果檢索不到,可能會新建一個),如果客戶端請求不包含session id,則為此客戶端創建一個session并且生成一個與此session相關聯的session id,session id的值應該是一個既不會重復,又不容易被找到規律以仿造的字符串,這個 session id將被在本次響應中返回給客戶端保存。
(1)Session與cookie
保存這個session id的方式可以采用cookie,這樣在交互過程中瀏覽器可以自動的按照規則把這個標識發揮給服務器。一般這個cookie的名字都是類似于SEEESIONID,而。比如weblogic對于web應用程序生成的cookie,JSESSIONID= ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764,它的名字就是 JSESSIONID。
(2)Session與URL
由于cookie可以被人為的禁止,必須有其他機制以便在cookie被禁止時仍然能夠把session id傳遞回服務器。經常被使用的一種技術叫做URL重寫,就是把session id直接附加在URL路徑的后面,附加方式也有兩種,一種是作為URL路徑的附加信息,表現形式為http://...../xxx;jsessionid= ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
另一種是作為查詢字符串附加在URL后面,表現形式為http://...../xxx?jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
(3)session在服務端的解析
這兩種方式對于用戶來說是沒有區別的,只是服務器在解析的時候處理的方式不同,采用第一種方式也有利于把session id的信息和正常程序參數區分開來。
為了在整個交互過程中始終保持狀態,就必須在每個客戶端可能請求的路徑后面都包含這個session id。