什么是Session


(4)Session(會話)

1)什么是Session?

服務器為了保存用戶狀態而創建的一個特殊的對象。

當瀏覽器第一次訪問服務器時,服務器創建一個session對象(該
對象有一個唯一的id,一般稱之為sessionId),服務器會將sessionId
以cookie的方式發送給瀏覽器。
當瀏覽器再次訪問服務器時,會將sessionId發送過來,服務器依據
sessionId就可以找到對應的session對象。

在 無連接(HTTP)協議基礎之上實現在用戶狀態管理。

2)如何獲得session對象?

方式一 HttpSession s = request.getSession(boolean flag);

    注:
        HttpSession是一個接口。
        當flag為true時:
                    先查看請求當中是否有sessionId,如果沒有,
                則創建一個session對象。如果有,則依據sessionId
                查找對應的session對象,如果找到了,則返回該
                對象,如果找不到,創建一個新的session對象。
        當flag為false時:
                    先查找請求當中是否有sessionId,如果沒有,
                返回null。如果有,則依據sessionId查找對應的session
                對象,如果找到了,則返回該對象,如果找不到,返回
                null。

方式二 HttpSession s = request.getSession();

等價於  request.getSession(true);  

3)常用方法

綁訂數據:

    session.setAttribute(String name,Object obj);

依據綁訂名獲得綁訂值:

    Object session.getAttribute(String name);
    注:如果綁訂名對應的值不存在,返回null。

解除綁訂:

    session.removeAttribute(String name);

利用這組方法共享一次會話期間相關的數據。

Session 的銷毀

為了避免Session中存儲的數據過大,Session需要銷毀:

  1. 超時自動銷毀。

    1. 從用戶最后一次訪問網站開始,超過一定時間后,服務器自動銷毀Session,以及保存在Session中的數據。
    2. Tomcat 服務器默認的Session超時時間是30分鍾
    3. 可以利用web.xml設置超時時間單位是分鍾,設置為0表示不銷毀。

      <session-config> <session-timeout>20</session-timeout> </session-config>

  2. 調用API方法,主動銷毀Session

    • session.invalidate()

案例:銷毀Servlet

public class DeleteServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        HttpSession session = request.getSession();
        session.invalidate();
        response.setContentType(
                "text/html; charset=utf-8");
        response.getWriter().println("呵呵!"); 
    }
}

過濾器 Filter

Servlet 標准中定義了過濾器,可以攔截任意的服務器請求和響應。

實現過濾器的步驟:

  1. 創建一個過濾器類實現javax.servlet.Filter接口
    • 重寫(實現)全部抽象方法
    • 業務邏輯寫到 doFilter中
    • 如果在doFilter中調用了 chain.doFilter方法則處理后續邏輯,如果不執行這個方法,表示對后續邏輯的攔截。
  2. 在web.xml(部署描述文件)配置filter,將filter配置到請求之前。

    • 可以配置多個filter-mapping,這樣可以復用同一個Filter
    • 可以使用 .png 或者 / 過濾一組url
    • 當有多個過濾器過濾統一個資源時候,按照配置的先后執行。

      <filter-name>demo</filter-name> <filter-class>web.DemoFilter</filter-class> <filter-mapping> <filter-name>demo</filter-name> <url-pattern>/img.png</url-pattern> </filter-mapping>

  3. 過濾器方法參數 ServletRequest 和 ServletResponse,是 HttpServletRequest 和 HttpServletResponse 的父類型,方法比較少! 如果需要使用HttpServletRequest 和 HttpServletResponse 的方法,需要進行強制類型轉換!

    1. 比如需要使用 request.getSession() 方法:

      HttpServletRequest req = (HttpServletRequest)request;
      HttpSession session = req.getSession();
      
  4. 利用 web.xml 可以向Filter 傳遞初始化參數。

    <init-param>
        <param-name>start</param-name>
        <param-value>8</param-value>
    </init-param>
    <init-param>
        <param-name>end</param-name>
        <param-value>17</param-value>
    </init-param>       
    
    config.getInitParamter("start");
    config.getInitParamter("end");
    
  5. Filter 對象的生命周期

    1. 在Web容器啟動時候創建Filter對象,Filter對象是單例的(只創建一個Filter對象)!
    2. 創建以后,立即執行init()方法,只執行一次
    3. 在有url請求時候,會執行匹配的doFilter(),doFilter()是並發執行的。
    4. Filter對象在容器關閉時候銷毀,銷毀時候執行destroy()

基本過濾器步驟:

  1. 編寫過濾器類:

    /**
     * 過濾器 Hello World! 
     */
    public class DemoFilter implements Filter {
        public void init(FilterConfig cfg) throws ServletException {
        }
        public void destroy() {
        }
        public void doFilter(ServletRequest req,
                ServletResponse res, FilterChain chain)
                throws IOException, ServletException {
            req.setAttribute("test", "試試"); 
    
            System.out.println("Hello World!");
            //處理后續請求:如果執行doFilter就正常處理后續
            //Web請求和響應,如果不執行doFilter就意味着
            //不處理后續請求和響應(也就是請求被攔截了!)
            chain.doFilter(req, res);
        }
    }
    
  2. 配置web.xml:

      <filter>
        <filter-name>demo</filter-name>
        <filter-class>web.DemoFilter</filter-class>
      </filter>
      <filter-mapping>
        <filter-name>demo</filter-name>
        <url-pattern>/img.png</url-pattern>
      </filter-mapping>
      <filter-mapping>
        <filter-name>demo</filter-name>
        <url-pattern>/test.html</url-pattern>
      </filter-mapping>
      <filter-mapping>
        <filter-name>demo</filter-name>
        <url-pattern>*.png</url-pattern>
      </filter-mapping>
    
  3. 測試

多個過濾可以連接使用:

  1. 編寫Servlet

    /**
     * 演示過濾器執行順序
     */
    public class TestFilter implements Filter {
    
        public void destroy() {
        }
    
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            String test = 
                    (String)request.getAttribute("test");
            System.out.println("Test Filter:"+test);
    
            chain.doFilter(request, response); 
        }
    
        public void init(FilterConfig fConfig) throws ServletException {
        }
    
    }
    
  2. 配置web.xml:

      <filter>
        <display-name>TestFilter</display-name>
        <filter-name>TestFilter</filter-name>
        <filter-class>web.TestFilter</filter-class>
      </filter>
      <filter-mapping>
        <filter-name>TestFilter</filter-name>
        <url-pattern>*.png</url-pattern>
      </filter-mapping>
    
  3. 測試

利用過濾器限制圖片的訪問:

  1. 編寫過濾器

    public class ImageFilter implements Filter {
        private int start, end; 
        public void destroy() {
            System.out.println("我還會回來的!");
        }
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            //獲取當前的時間
            Calendar cal = Calendar.getInstance();
            //獲取小時分量
            int hour = cal.get(Calendar.HOUR_OF_DAY);
            //在start到下午end之前,可以看見圖片
            if(hour>start && hour<end) {
                chain.doFilter(request, response);
            }else {
                response.setContentType(
                        "text/html; charset=UTF-8");
                response.getWriter().println("系統繁忙!"); 
            }
        }
    
        public void init(FilterConfig fConfig) throws ServletException {
            //讀取web.xml文件中的配置參數
            String s1=fConfig.getInitParameter("start");
            String s2=fConfig.getInitParameter("end");
            start = Integer.parseInt(s1);
            end = Integer.parseInt(s2);
            System.out.println(start+","+end); 
        }
    
    }
    
  2. 配置 web.xml

      <filter>
        <display-name>ImageFilter</display-name>
        <filter-name>ImageFilter</filter-name>
        <filter-class>web.ImageFilter</filter-class>
        <init-param>
          <param-name>start</param-name>
          <param-value>8</param-value>
        </init-param>
        <init-param>
          <param-name>end</param-name>
          <param-value>17</param-value>
        </init-param>
      </filter>
      <filter-mapping>
        <filter-name>ImageFilter</filter-name>
        <url-pattern>*.png</url-pattern>
      </filter-mapping>
    
  3. 測試

監聽器

在Web容器的工作時候,在出現特定情況下,會自動的執行用戶定義的監聽器程序。利用監聽器程序,可以將用戶程序嵌入到Web容器中工作。

特定情況包括:

  1. 對象創建情況:
    1. request對象,response對象,session對象,ServletContext對象等。
    2. 對象的創建和銷毀時候執行 事件代碼。
  2. 在對象中添加、刪除數據時候(setAttribute,removeAttribute)
  3. 其他的工作狀態改變的時候。

如使用: HttpSessionListener

  1. 創建 類 實現HttpSessionListener
    • 重寫方法 sessionCreated()
    • 重寫方法 sessionDestroyed()
  2. 在web.xml 中配置
  3. 啟動web容器
    1. 當web容器工作期間創建了session對象時候,會自動執行 sessionCreated()
    2. 當web容器工作期間銷毀了session對象時候, 會自動執行sessionDestroyed()

案例:

/**
 * 監聽器演示案例 
 */
public class DemoListener 
    implements  HttpSessionListener {
    //在Session對象創建以后執行
    public void sessionCreated(HttpSessionEvent e) {
        System.out.println("Hello Session Created");
        //e 代表當前事件發生時候的相關數據。
        HttpSession s = e.getSession();
        System.out.println("SID:"+s.getId()); 
    }
    //在Session對象銷毀以后執行
    public void sessionDestroyed(HttpSessionEvent e) {
        System.out.println("Hello Session Destroyed");
    }
}

  <listener>
    <listener-class>web.DemoListener</listener-class>
  </listener>

如上功能的意義:在session創建銷毀時候插入用戶自定義的代碼。

最重要的監聽器:ServletContextListener

  1. contextInitialized() 會在Web服務器啟動時候執行。 在軟件中需要初始化的程序寫到這個方法中。
  2. contextDestoryed() 會在Web服務器關閉時候執行。如果需要在關閉時候清除的資源,可以寫到這個方法中。

案例:

public class InitListener implements ServletContextListener {

    //在web服務器關閉時候執行
    public void contextDestroyed(ServletContextEvent e)  { 
        System.out.println("Hello contextDestroyed");
    }
    //在web服務器啟動時候執行,用於初始化資源
    public void contextInitialized(ServletContextEvent e)  { 
        System.out.println("Hello contextInitialized");
    }

}

  <listener>
    <listener-class>web.InitListener</listener-class>
  </listener>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM