一、基於Cookie實現Sessionhtml
Session對象的原理在於,服務器能夠爲客戶端建立並維護一個所謂的Session對象,用於存放數據。在建立Session對象的同時,服務 器將會爲該Session對象產生一個惟一編號,這個編號稱之爲SessionID,服務器以Cookie的方式將SessionID存放在客戶端。當瀏 覽器再次訪問該服務器時,會將SessionID做爲Cookie信息帶到服務器,服務器能夠經過該SessionID檢索到之前的Session對象, 並對其進行訪問。須要注意的是,此時的Cookie中僅僅保存了一個SessionID,而相對較多的會話數據保存在服務器端對應的Session對象 中,由服務器來統一維護,這樣必定程度保證了會話數據安全性,但增長了服務器端的內存開銷。
存放在客戶端的用於保存SessionID的Cookie會在瀏覽器關閉時清除。咱們把用戶打開一個瀏覽器訪問某個應用開始,到關閉瀏覽器爲止交互過程稱 爲一個「會話」。在一個「會話」過程當中,可能會向同一個應用發出了屢次請求,這些請求將共享一個Session對象,由於這些請求攜帶了相同的 SessionID信息。java
下面的Servlet用來演示Session的工做原理:
瀏覽器
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); String option = request.getParameter("option"); if ("create".equals(option)) { //得到HttpSession對象 HttpSession session = request.getSession(); //設置Session對象的最長不活動間隔 session.setMaxInactiveInterval(30); //獲取Session中的數據 List list = (List) session.getAttribute("list"); if (list == null) { list = new ArrayList(); list.add("hey"); //向Session中添加數據 session.setAttribute("list", list); } else { list.add("hey"); } out.println(list); }elseif ("invalidate".equals(option)) { HttpSession session = request.getSession(false); if (session != null) { //使Session對象失效 session.invalidate(); } }
該Servlet的url-pattern爲/testSession。
當瀏覽器請求地址「.../tst/testSession?option=create」時,Servlet調用request的getSession 方法得到Session對象,若是此時服務器端存在與請求信息中SessionID(做爲Cookie信息攜帶)對應的Session對象,則返回這個 Session對象,不然將會建立一個新的Session對象並將其產生的SessionID以Cookie的形式經過響應信息送回。注 意,Session對象的setMaxInactiveInterval方法用於設置最長不活動間隔,單位是秒,若是出如今這個的時間段內Session 對象沒有被存取,則該Session對象將會失效。一般爲了保證服務器的性能和出於安全性考慮,這個值要妥善的設置(Tomcat針對Session的 MaxInactiveInterval會有默認的設置)。若setMaxInactiveInterval設置爲負值,則表示該Session永不過 期。另外,Session對象分別經過setAttribute和getAttribute方法存取數據,數據以「名稱-對象」對的形式存放。該請求對應 的請求和響應的HTTP信息爲:安全
請求: GET /tst/testSession?option=create HTTP/1.1 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/x-silverlight, ** Accept-Language: zh-cn UA-CPU: x86 Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1) Host: 192.168.5.100:8080 Connection: Keep-Alive Cookie: JSESSIONID=C69B3053C575ECC8C7FCAF7D189A4FD1 響應 HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Content-Type: text/html;charset=ISO-8859-1 Content-Length: 12 Date: Sun, 29 Jun 2008 07:20:41 GMT [hey, hey]
注意:請求信息中攜帶的SessionID值與上一次相應的SessionID之一致。另外響應輸出的HTML文本中有兩個「hey」,這是由於此次請求Servlet往存放在Session中的list對象中又放置了一個String對象。
當瀏覽器請求「.../tst/testSession?option=invalidate」時,Servlet會調用Session對象的 invalidate方法用於使該Session對象失效。須要注意的是,此時獲取Session對象的方法爲重載的 getSession(boolean b)其中boolean類型的參數表示當前請求沒有和服務器端的某個Session對象關聯時是建立新的Session(參數爲true時)仍是返回 null(參數爲false時)。服務器
二、基於URL重寫 從上面的介紹能夠看出,Session對象的正常使用要依賴於Cookie。若是考慮到客戶端瀏覽器可能出於安全的考慮禁用了Cookie,應該使用URL重寫的方式使Session在客戶端禁用Cookie的狀況下繼續生效。
下面有兩個JSP頁面:1.jsp中向Session對象中存入了名爲「hi」的一個String類型對象。經過超級連接能夠連接到2.jsp,在 2.jsp中將獲取Session中名爲「hi」的對象,並顯示在頁面上。須要注意的是:在1.jsp中超級連接的地址並非直接寫了「2.jsp」而是 經過resopnse的encodeURL方法對這個地址進行了處理。session
1.jsp <% session.setAttribute("hi","Do you work or are you a student?"); %> <a href="<%=response.encodeURL("2.jsp")%>">2.jsp</a> 2.jsp <%=session.getAttribute("hi")%>
首先將瀏覽器的Cookie禁用(注意要重啓IE),而後請求1.jsp,響應後點擊連接到2.jsp,這個交互過程涉及到兩次請求和相應,HTTP信息以下:app
請求1.jsp GET /tst/session/1.jsp HTTP/1.1 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/x-silverlight, ** Referer: http://192.168.5.100:8080/tst/session/1.jsp Accept-Language: zh-cn UA-CPU: x86 Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1) Host: 192.168.5.100:8080 Connection: Keep-Alive 響應: HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Content-Type: text/html;charset=ISO-8859-1 Content-Length: 33 Date: Sun, 29 Jun 2008 07:31:36 GMT Do you work or are you a student?
注意:因爲Cookie的禁用,此次請求協議頭中雖然沒有攜帶SessionID的信息,但SessionID的信息做爲請求地址的一部分傳到了服務器端,這就是URL重寫的意義所在。
response的encodeURL方法將根據瀏覽器是否不支持Cookie決定是否將SessionID信息寫入連接地址。
jsp