1. 程式人生 > >JavaWeb從入門到精通(四)-會話管理

JavaWeb從入門到精通(四)-會話管理

1 課程回顧

Servlet程式設計

          1)Servlet生命週期(重點)

                   構造方法:建立servlet物件。預設情況下,第一次訪問servlet物件時。只調用1次。

                   init方法(有參):建立完servlet物件後呼叫。只調用1次。

                                     注意:會呼叫無參的init方法。

                   service方法: servlet提供服務的方法。每次發出請求呼叫。

                                     注意: request物件 ,response物件

                   destroy方法: tomcat伺服器停止或web應用重新部署,servlet物件銷燬,destroy方法被呼叫。

         2)ServletConfig物件

                            獲取servlet的初始化引數:

                                     getInitParameter("name         ");

                                     getInitParameterNames();

         3)ServletContext物件

                            得到web應用路徑:

                                               context.getContextPath();

                                               request.getContextPath();  等價於上面的程式碼

                            得到web應用引數:

                                               context.getInitParameter("name");

                                               context.getInitParameterNames();

                            域物件:

                                               context.setAttribute("name",Object):儲存資料

                                               context.getAttribute("name")   得到資料

                                               context.removeAttribue("name")  清除資料

                            轉發

                                               context.getRequestDispatcher("路徑").forward(request,response);

                                               request.getRequestDispacher("路徑").forward(request,response); 等價於上面的程式碼

                            得到web應用中的資原始檔

                                               context.getRealPath("路徑")

                                               context.getResourceAsStream("路徑");

路徑問題:

publicvoid doGet(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {

                   response.setContentType("text/html;charset=utf-8");

                   //目標資源: target.html

                   /**

                    * 思考: 目標資源是給誰使用的。

                    *             給伺服器使用的:   / 表示在當前web應用的根目錄(webRoot下)

                    *             給瀏覽器使用的: /  表示在webapps的根目錄下

                    */

                   //1.轉發(給伺服器使用)

                   request.getRequestDispatcher("/target.html").forward(request, response);

                   //2.請求重定向(給瀏覽器使用)

                   response.sendRedirect("/day11/target.html");

                   // 3.html頁面的超連線href

                   response.getWriter().write("<html><body><ahref='/day11/target.html'>超連結</a></body></html>");

                   // 4.html頁面中的form提交地址

                   response.getWriter().write("<html><body><formaction='/day11/target.html'><inputtype='submit'/></form></body></html>");

         }

讀取web應用下的資原始檔(例如properties):

/**

                    *  . 代表java命令執行目錄。java執行命令在哪裡??在tomcat/bin目錄下

                    *   結論:在web專案中, . 代表在tomcat/bin目錄下開始,所以不能使用這種相對路徑。

                    */

                   //讀取檔案。在web專案下不要這樣讀取。因為.表示在tomcat/bin目錄下

                   /*Filefile = new File("./src/db.properties");

                   FileInputStreamin = new FileInputStream(file);*/

                   /**

                    * 使用web應用下載入資原始檔的方法

                    */

                   /**

                    * 1. getRealPath讀取,返回資原始檔的絕對路徑

                    */

                   /*Stringpath =this.getServletContext().getRealPath("/WEB-INF/classes/db.properties");

                   System.out.println(path);

                   Filefile = new File(path);

                   FileInputStreamin = new FileInputStream(file);*/

                   /**

                    * 2. getResourceAsStream() 得到資原始檔,返回的是輸入流

                    */

                   InputStreamin =this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");

                   Propertiesprop = new Properties();

                   //讀取資原始檔

                   prop.load(in);

                   Stringuser = prop.getProperty("user");

                   Stringpassword = prop.getProperty("password");

                   System.out.println("user="+user);

                   System.out.println("password="+password);

2. 會話管理入門     

              2.1 生活中會話

                            我:小張,你會跳小蘋果碼?

                            小張:會,怎麼了?

                            我:公司年會上要表演節目,你教教我把

                            小張:沒問題,一頓飯而已。

                            我: OK。

                            。。。。。。。。

                            在這次生活中的會話中產生通話記錄(會話資料)

              2.2 軟體中的會話

                   一次會話:開啟瀏覽器 -> 訪問一些伺服器內容 -> 關閉瀏覽器

                   登入場景:

                            開啟瀏覽器 -> 瀏覽到登陸頁面 -> 輸入使用者名稱和密碼 -> 訪問到使用者主頁(顯示使用者名稱)

                                                                                                                                                     修改密碼(輸入原密碼)

                                                                                                                                                      修改收貨地址

                                                                                                                                                     .......

                            問題:在此處登入會話過程中產生的資料(使用者會話資料)如何儲存下來呢?

                   購物場景:

                             開啟瀏覽器 -> 瀏覽商品列表  -> 加入購物車(把商品資訊儲存下來)  -> 關閉瀏覽器

                             開啟瀏覽器->  直接進入購物車 -> 檢視到上次加入購物車的商品 -> 下訂單 -> 支付

                            問題:在購物會話過程中,如何儲存商品資訊??

                   會話管理:管理瀏覽器客戶端伺服器端之間會話過程中產生的會話資料。

域物件: 實現資源之間的資料共享。

                            request域物件

                            context域物件

                   登入場景:

                            小張:輸入“張三” (儲存資料:context.setAttribute("name","張三")) -> 使用者主頁(顯示“張三”)

                            小李:輸入“李四”(儲存資料:context.setAttribute("name","李四")) -> 使用者主頁(顯示“李四”)

                                               問題: context是所有使用者公有的資源!!!會覆蓋資料。

                            小張:輸入“張三”(儲存資料:request.setAttribute("name","張三"))- > 使用者主頁(顯示“張三”)                                               問題:一定要使用轉發技術來跳轉頁面!!!

                   解決辦法:可以使用session域物件來儲存會話資料!!!

              2.3 會話技術

                            Cookie技術:會話資料儲存在瀏覽器客戶端。

                            Session技術:會話資料儲存在伺服器端。

3 Cooke技術

                     3.1特點

                            Cookie技術:會話資料儲存在瀏覽器客戶端。

                     3.2Cookie技術核心

                            Cookie類:用於儲存會話資料

                                     1)構造Cookie物件

                                               Cookie(java.lang.Stringname, java.lang.String value)

                                     2)設定cookie

                                               voidsetPath(java.lang.String uri)   :設定cookie的有效訪問路徑

                                               voidsetMaxAge(int expiry) : 設定cookie的有效時間

                                               voidsetValue(java.lang.String newValue) :設定cookie的值

                                     3)傳送cookie到瀏覽器端儲存

                                               voidresponse.addCookie(Cookie cookie)  : 傳送cookie

                                     4)伺服器接收cookie

                                               Cookie[]request.getCookies()  : 接收cookie

                     3.3Cookie原理

                                     1)伺服器建立cookie物件,把會話資料儲存到cookie物件中。

                                                        newCookie("name","value");

                                     2)  伺服器傳送cookie資訊到瀏覽器

                                                        response.addCookie(cookie);

                                               舉例: set-cookie:name=eric  (隱藏傳送了一個set-cookie名稱的響應頭)

                                     3)瀏覽器得到伺服器傳送的cookie,然後儲存在瀏覽器端。

                                     4)瀏覽器在下次訪問伺服器時,會帶著cookie資訊

                                                  舉例: cookie: name=eric (隱藏帶著一個叫cookie名稱的請求頭)

                                     5)伺服器接收到瀏覽器帶來的cookie資訊

                                                        request.getCookies();

                     3.4Cookie的細節

                            1)void setPath(java.lang.String uri)  :設定cookie的有效訪問路徑。有效路徑指的是cookie的有效路徑儲存在哪裡,那麼瀏覽器在有效路徑下訪問伺服器時就會帶著cookie資訊,否則不帶cookie資訊。

                            2)void setMaxAge(int expiry) : 設定cookie的有效時間。

                                               正整數:表示cookie資料儲存瀏覽器的快取目錄(硬碟中),數值表示儲存的時間。

                                               負整數:表示cookie資料儲存瀏覽器的記憶體中。瀏覽器關閉cookie就丟失了!!

                                               零:表示刪除同名的cookie資料

                            3)Cookie資料型別只能儲存非中文字串型別的。可以儲存多個cookie,但是瀏覽器一般只允許存放300個Cookie,每個站點最多存放20個Cookie,每個Cookie的大小限制為4KB。

                     3.5案例- 顯示使用者上次訪問的時間

                     3.6案例-檢視使用者瀏覽器過的商品

4 Session技術

                     4.1引入

                            Cookie的侷限:

                                     1)Cookie只能存字串型別。不能儲存物件

                                     2)只能存非中文。

                                     3)1個Cookie的容量不超過4KB。

                            如果要儲存非字串,超過4kb內容,只能使用session技術!!!

                            Session特點:

會話資料儲存在伺服器端。(記憶體中)

                     4.2Session技術核心

                            HttpSession類:用於儲存會話資料

                            1)建立或得到session物件

                                     HttpSession getSession() 

                                     HttpSession getSession(booleancreate) 

                            2)設定session物件

                                     void setMaxInactiveInterval(intinterval)  設定session的有效時間

                                     void invalidate()     銷燬session物件

                                     java.lang.String getId()  得到session編號

                            3)儲存會話資料到session物件

                                     voidsetAttribute(java.lang.String name, java.lang.Object value)  儲存資料

                                     java.lang.ObjectgetAttribute(java.lang.String name)  獲取資料

                                     voidremoveAttribute(java.lang.String name) 清除資料

                     4.3Session原理

                                     問題:伺服器能夠識別不同的瀏覽者!!!

                            現象:

            前提: 在哪個session域物件儲存資料,就必須從哪個域物件取出!!!!

                            瀏覽器1:(給s1分配一個唯一的標記:s001,把s001傳送給瀏覽器)

                                               1)建立session物件,儲存會話資料

                                                                  HttpSessionsession = request.getSession();   --儲存會話資料 s1

                            瀏覽器1 的新視窗(帶著s001的標記到伺服器查詢,s001->s1,返回s1)  

                                               1)得到session物件的會話資料

                                                            HttpSession session = request.getSession();   --可以取出  s1

                            新的瀏覽器1:(沒有帶s001,不能返回s1)

                                               1)得到session物件的會話資料

                                                            HttpSession session = request.getSession();   --不可以取出  s2

                            瀏覽器2:(沒有帶s001,不能返回s1)

                                               1)得到session物件的會話資料

                                                            HttpSession session = request.getSession();  --不可以取出  s3

                            程式碼解讀:HttpSession session = request.getSession();

                            1)第一次訪問建立session物件,給session物件分配一個唯一的ID,叫JSESSIONID

                                               newHttpSession();

                            2)把JSESSIONID作為Cookie的值傳送給瀏覽器儲存

                                               Cookiecookie = new Cookie("JSESSIONID", sessionID);

                                               response.addCookie(cookie);

                            3)第二次訪問的時候,瀏覽器帶著JSESSIONID的cookie訪問伺服器

                            4)伺服器得到JSESSIONID,在伺服器的記憶體中搜索是否存放對應編號的session物件。

                                               if(找到){

                                                        returnmap.get(sessionID);

                                               }

                                               Map<String,HttpSession>]

                                               <"s001",s1>

                                               <"s001,"s2>

                            5)如果找到對應編號的session物件,直接返回該物件

                            6)如果找不到對應編號的session物件,建立新的session物件,繼續走1的流程

                   結論:通過JSESSIONcookie值在伺服器找session物件!!!!!

                     4.4Sesson細節

                            1)java.lang.String getId()  :得到session編號

                            2)兩個getSession方法:

                                               getSession(true)/ getSession()  : 建立或得到session物件。沒有匹配的session編號,自動創                                                                                                                建新的session物件。

                                               getSession(false):              得到session物件。沒有匹配的session編號,返回null

                            3)void setMaxInactiveInterval(int interval)  : 設定session的有效時間

                                                        session物件銷燬時間:

                                                                 3.1預設情況30分伺服器自動回收

                                                                 3.2修改session回收時間

                                                                 3.3全域性修改session有效時間

<!-- 修改session全域性有效時間:分鐘 -->

    <session-config>

       <session-timeout>1</session-timeout>

    </session-config>

                                                                 3.4.手動銷燬session物件

                                                                           void invalidate()     :銷燬session物件

                            4)如何避免瀏覽器的JSESSIONID的cookie隨著瀏覽器關閉而丟失的問題

/**

        * 手動傳送一個硬碟儲存的cookie給瀏覽器

        */

       Cookie c = new Cookie("JSESSIONID",session.getId());

       c.setMaxAge(60*60);

       response.addCookie(c);

                   總結:

                                     1)會話管理:瀏覽器和伺服器會話過程中的產生的會話資料的管理。

                                     2)Cookie技術:

                                                        newCookie("name","value")

                                                        response.addCookie(coookie)

                                                        request.getCookies()

                                     3)Session技術

                                                        request.getSession();

                                                        setAttrbute("name","會話資料");

                                                        getAttribute("會話資料")