【JSP/Servlet-HTTP會話解析】

來源:互聯網
上載者:User

標籤:style   blog   http   color   os   io   使用   java   ar   


個人學習整理,如有不足之處,請不吝指教。轉載請註明:@CSU-Max


Max之前的一篇關於Session 和 Cookie 的文章:cookie和session那些事
會話簡介
web伺服器跟蹤客戶狀態的幾種方式:   1、在html表單中加入隱藏欄位,它包含用於跟蹤使用者狀態的資料;   2、重寫URL,及在URL中附帶使用者的狀態資訊;   3、使用cookie來傳遞用於跟蹤客戶狀態的資料;   4、使用會話來跟蹤使用者狀態的資料。
   會話能夠把使用者與同一使用者發出的不同請求之間關聯起來。不同使用者的會話應當是相互獨立的。在web開發領域,會話機制是用於跟蹤使用者狀態的普遍解決方案。會話是指在一段時間內,單個使用者與web應用的一系列互動過程。在一個會話過程中,使用者可以多次請求該web應用的同一頁面,也可以訪問該web應用中的其他頁面。
   在Servlet中有關於會話的 javax.servlet.http.HttpSession 介面,Servlet容器必須實現這一介面。當一個會話開始時,Servlet容器會建立一個HttpSession對象,將客戶資訊狀態儲存在該對象中,如購物車資訊。Servlet容器為每個HttpSession對象分配一個唯一的標誌符,稱為SessionID。
會話的運作流程      1、當一個瀏覽器進程第一次請求訪問某個web應用中任意一個支援會話的網頁(也可以設定頁面不支援會話,下文有介紹),Servlet容器會試圖尋找HTTP請求中表示SessionID的Cookie,由於還不存在這樣的Cookie,故此時就會開啟一個新的會話,Servlet容器會建立一個HttpSession對象,並為其分配一個唯一的SessionID,在返回HTTP響應結果時,Cookie會附帶該SessionID。當瀏覽器接收到HTTP響應結果之後,會把Cookie(帶有SessionID)儲存在用戶端。      2、該瀏覽器進程繼續訪問該web應用中的任意支援會話的頁面,在本次的HTTP請求中會包含帶有SessionID的Cookie,Servlet容器會擷取本次HTTP請求中的SessionID,該SessionID就是1中產生的,因此Servlet容器認為本次請求與上次請求處於同一個會話中,Servlet容器不會建立新的HttpSession對象,而是根據Cookie中的SessionID,找到記憶體中該SessionID對應的HttpSession對象。
   3、重複步驟2,在當前會話銷毀之前(關於會話的銷毀下文有介紹),仍是在同一個會話中進行訪問,故不會產生新的HttpSession對象。
通過代碼執行個體來瞭解會話機制
    在預設情況下,JSP頁面都會支援會話,也可以通過代碼顯式控制支援會話:

<%@ page session = "true" %>


   若web組件支援會話,當客戶請求訪問該web組件時,Servlet容器會自動尋找HTTP請求中表示SessionID的Cookie,並向HTTP響應結果中添加表示SessionID的Cookie。在此過程中,若有與SessionID對應的HttpSession對象,則Servlet容器使用該對象,若沒有,則Servlet容器會建立一個新的HttpSession對象。web組件可以訪問代表當前會話的HttpSession對象。
   我們可以通過下面的執行個體代碼來瞭解,建立一個web工程,在根目錄下建立一個test.jsp,具體代碼如下:
<%@ page language ="java" contentType="text/html; charset=utf-8"      pageEncoding= "utf-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv= "Content-Type" content ="text/html; charset=utf-8"><title> Insert title here</ title></head><body>     <%          Cookie[] cookies = request.getCookies();           if (cookies == null) {              out.println( "no cookie");               return;          }           for ( int i = 0; i < cookies.length; i++) {     %>     <b >Cookie Name </b>     <%=cookies[i].getName() %>     <br >     <b >Cookie Value </b>     <%=cookies[i].getValue() %>     <br >     <b >Cookie Maxage</ b>     <%=cookies[i].getMaxAge() %>     <%          }     %></body></html>


   1、開啟一個瀏覽器進程,第一次請求訪問test.jsp頁面,會返回“no cookie”。      


   2、利用1開啟的瀏覽器進程,再次訪問test.jsp頁面(即再按一次斷行符號即可)。由於在1中,Servlet容器會向用戶端發送一個包含SessionID的Cookie(上面已經講到),所以本次的HTTP請求中會包含該Cookie,故test.jsp頁面上會顯示該Cookie的資料,如:

      


註:此處Cookie的maxage(有效期間)屬性值為 -1,表示該Cookie僅存在與當前的瀏覽器進程中,當瀏覽器關閉,該Cookie也就失效了,本次會話也結束了。
   3、利用1開啟的瀏覽器進程再多次訪問test.jsp頁面,頁面顯示的資料仍如所示。      
   4、重新打來一個瀏覽器進程,重複步驟1、2、3,會發現頁面顯示的Cookie Value不一樣,即SessionID不一樣,因為不同的瀏覽器進程對應不同的會話,每個會話都擁有一個唯一的SesionID。
   5、在test.jsp中加入如下代碼,使test.jsp不支援會話,再重新開啟一個瀏覽器進程,多次訪問test.jsp頁面,結果都是顯示“no cookie”。因為test.jsp顯式要求不支援會話,所以Servlet容器不會建立HttpSession對象,也不會向用戶端發送表示SessionID的Cookie。

HttpSession 的會話範圍      會話的範圍指的是瀏覽器端與一個web應用進行一次會話的過程。在具體實現時,會話範圍與HttpSession對象的生命週期相對應,所以web組件只要共用同一個HttpSession對象,就能實現共用工作階段範圍內的共用資料。在HttpSession介面中關於在會話範圍記憶體取共用資料有如下方法:
 /**      * 向會話範圍記憶體放共用資料      */     public void setAttribute(String name, Object value) {     }     /**      * 返回會話範圍內與name對應的共用資料      */     public Object getAttribute(String name) {           return null;     }     /**      * 返回會話範圍內所有共用資料的name      */     public Enumeration getAttributeNames() {           return null;     }     /**      * 刪除會話範圍內與name對應的共用資料      */     public void removeAttribute(String name) {     }

            利用以上的方法,我們就可以在會話範圍記憶體取共用資料了:
  HttpSession session = request.getSession();           //將username 儲存到會話範圍內的共用資料中          session.setAttribute( "username", username);           //從會話範圍內讀取username          currentUser = (String) session.getAttribute("username" );


   在HttpSession介面中還有一些其他的訪問會話的方法,想瞭解的可以自行研究。
HttpSession 的生命週期
   在以下情況下,會 開啟一個新的會話,即Servlet容器會建立一個新的HttpSession對象:   1、一個瀏覽器進程第一次訪問某個web應用中支援會話的任意一個網頁。   2、當瀏覽器與web應用的上一次會話被銷毀後,瀏覽器進程再次訪問web應用中支援會話的任意一個網頁。
註:當瀏覽器進程與web應用的一次會話被銷毀之後,web伺服器端相應的HttpSession對象結束其生命週期。當瀏覽器進程再次訪問該web應用時,在它的HTTP請求中的Cookie中包含了之前已被銷毀的SessionID,但是此時Servlet容器無法找到次SessionID對應的HttpSession對象,故Servlet容器會建立新的HttpSession對象,開啟新的會話。
   在以下情況下,會 銷毀一個會話,即Servlet容器會使HttpSession對象結束生命週期,並且儲存在會話範圍內的共用資料也會被銷毀:   1、瀏覽器進程終止。   2、伺服器端執行了HttpSession對象的invalidate()方法。   3、會話到期。      會話到期是指在會話開啟之後,若在一段規定的時間內,使用者沒用和web應用進行互動,則Servlet容器會自動的銷毀這個會話。HttpSession中的 setMaxInactiveInterval(int interval) 方法用於設定允許會話保持不活動狀態的時間(以秒為單位),如果超過這個規定的時間,會話就會被Servlet容器銷毀。若把 interval 參數設為負數,則表示會話永遠不會到期。在Tomcat中,預設的會話保持不活動狀態的時間是1800秒。
   當一個會話開啟後,如果瀏覽器進程突然關閉,Servlet容器無法立即知道瀏覽器進程已經關閉,因此Servlet容器中的HttpSession對象不會立即結束生命週期,會話會在瀏覽器進程關閉之後,進入不活動狀態,等到超出上述規定的時間後,會話就會因為到期而被Servlet容器銷毀。
為什麼要有會話到期的機制呢?      我們知道,過多無用的HttpSession對象會影響web伺服器的效能,銷毀長期不活動的會話,可以及時釋放這些HttpSession對象佔用的記憶體空間。同時,會話到期機制也提高了web應用的安全性,防止未授權的使用者訪問會話。如某個使用者訪問某個web應用,之後並沒有關閉瀏覽器進程,此時另一個使用者使用該瀏覽器進程訪問同一web應用,此時看到的是前一個使用者的資訊,這就給安全帶來了隱患。


 ********************************************************************************

 **          轉載請註明出處:  @CSU-Max    http://blog.csdn.net/csu_max          **     ********************************************************************************



【JSP/Servlet-HTTP會話解析】

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.