1. 程式人生 > >HttpSession implements session

HttpSession implements session

內存空間 reat sub gif getattr -c 執行 ttr write

體驗

  使用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()方法,設定瀏覽器多久沒有請求

應用程序,HttpSession就自動失效,單位是“秒”。也可以在web.xml中設定HttpSession默認的失效時間,單位是“分鐘”


新接口

  在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

技術分享圖片
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 技術分享圖片
<?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