HttpSession implements session
體驗
使用HttpSession進行會話管理,完全可以忽略HTTP無狀態的事實。
HttpSession會話管理原理
使用HttpSession進行會話管理十分方便,讓Web應用程序看似可以“記得”瀏覽器發出的請求,連接數個請求間的關系。但無論如何,Web應用程序基於HTTP協議的事實並沒有改變。這背後Web容器幫我們做了一些工作。
當第一次調用HttpServletRequest的getSession()時,Web容器會創建一個HttpSession對象,每個HttpSession對象都有個特殊的ID,這個Session ID默認會使用Cookie存放在瀏覽器中。當瀏覽器再次請求應用程序時,會將Cookie中存放的Session ID一並發送給應用程序,Web容器就能根據Session ID來找出對應的HttpSession對象,這樣就可以取得各個瀏覽器的會話數據。
存儲Session ID的cookie
存儲Session ID的Cookie “默認”為關閉瀏覽器就失效,所以重啟瀏覽器請求應用程序時,通過getSession()取得的是新的HttpSession對象。註意默認關閉瀏覽器馬上失效的是瀏覽器上的Cookie,而不是HttpSession。因為Cookie失效了,就無法通過Cookie來發送Session ID,所以使用getSession()時,容器會產生新的HttpSession。
HttpSession
要讓HttpSession立即失效必須運行invalidate()方法,否則的話,HttpSession會等到設定的失效期間過後才會被容器銷毀回收。
可以執行HttpSession的setMaxInactiveInterval()方法,設定瀏覽器多久沒有請求
新接口
在Servlet 3.0中新增了SessionCookieConfig接口,可以通過ServletContext的getSessionCookieConfig()來取得實現該接口的對象,通過該對象可以設定存儲Session ID的Cookie的相關信息,例如可以通過setName()將默認的名稱(在Tomcat中,Cookie的默認名稱是JSESSIONID)修改為別的名稱,通過setAge()設定存儲Session ID的Cookie存活期限等,單位是“秒”。
但是註意,設定SessionCookieConfig必須在ServletContext初始化之前,所以實際上修改存儲Session ID的Cookie存活期限等信息時有兩種方法:
1、在web.xml中設定
2、實現ServletContextListener,容器在初始化ServletContext時會調用ServletContextListener的contextInitialized()方法,可以在其中取得ServletContext進行SessionCookieConfig設定。
占用內存
HttpSession對象會占用服務器內存空間,所以HttpSession中盡量不要存儲耗資源的大型對象,必要時將屬性移除,或者不需使用HttpSession時,執行invalidate()讓HttpSession失效。
線程安全
HttpSession並非線程安全,所以必須註意屬性設定時共享存取的問題。
example
![技術分享圖片](/img/jia.gif)
package com.test; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; import java.io.PrintWriter; @WebServlet("/questionnaire") public class Questionnaire extends HttpServlet { protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); out.println("<!DOCTYPE html>"); out.println("<html>"); out.println("<head>"); out.println("<meta charset=‘UTF-8‘>"); out.println("<title>問卷調查</title>"); out.println("</head>"); out.println("<body>"); String page = request.getParameter("page"); out.println("<form action=‘questionnaire‘ method=‘get‘>"); if(page == null) { // 第一頁問卷 out.println("問題一:<input type=‘text‘ name=‘p1q1‘><br>"); out.println("問題二:<input type=‘text‘ name=‘p1q2‘><br>"); out.println("<input type=‘submit‘ name=‘page‘ value=‘page2‘>"); } else if("page2".equals(page)) { // 第二頁問卷 HttpSession session = request.getSession(); session.setAttribute("p1q1", request.getParameter("p1q1")); session.setAttribute("p1q2", request.getParameter("p1q2")); //session.invalidate(); // 銷毀session out.println("問題三:<input type=‘text‘ name=‘p2q1‘><br>"); out.println("<input type=‘submit‘ name=‘page‘ value=‘finish‘>"); } else if("finish".equals(page)) { // 最後答案收集 HttpSession session = request.getSession(); out.println(session.getAttribute("p1q1") + "<br>"); out.println(session.getAttribute("p1q2") + "<br>"); out.println(request.getParameter("p2q1") + "<br>"); } out.println("</form>"); out.println("</body>"); out.println("</html>"); out.close(); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } }View Code
![技術分享圖片](/img/jia.gif)
<?xml version="1.1" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <display-name>Archetype Created Web Application</display-name> <session-config> <session-timeout>30</session-timeout> <cookie-config> <name>my-session-id</name> <!-- js 無法讀取cookie --> <http-only>true</http-only> <!-- 單位是秒 --> <max-age>5</max-age> </cookie-config> </session-config> </web-app>View Code
測試方法:
1、測試關閉瀏覽器cookie失效,原來的session對象無法找到
(1)訪問:http://127.0.0.1:8000/questionnaire
(2)填寫表單並提交,提交後服務器端會往session寫入數據
(3)關閉瀏覽器
(4)訪問:http://127.0.0.1:8000/questionnaire?p2q1=123&page=finish
2、SessionCookieConfig測試
查看web.xml
HttpSession implements session