web基礎---->session的使用


前幾天在博問中,看到有人提到了有關session的問題,決定自己整理寫一下有關session的原理!說起session,cookie必須是要談的!

 

目錄

  1. Cookie的介紹
  2. Cookie的使用
  3. Session的介紹
  4. Session的使用
  5. Session的原理

 

Cookie的介紹(參照計算機網絡)

一、無形之中我們使用的cookie:

使用瀏覽器瀏覽網頁時,當你要登陸時,網頁上有一個記住密碼或自動登陸的選項,當你選擇時,你就使用了Cookie。那么在下次訪問該網站時,你可能就已經自動地登陸了,而不需要從重輸入用戶名和密碼

二、cookie技術的組成
  • 在HTTP響應報文中有一個cookie首部行;
  • 在HTTP請求報文中有一個cookie首部行;
  • 在用戶端系統中保留有一個cookie文件,由用戶瀏覽器管理;
  • 在Web站點有一個后端數據庫;
三、cookie的工作原理
在了解了cookie技術的組成之后,我們來看看cookie是怎么工作的。下面就以主機A中的瀏覽器訪問網站xxx作為例子來分析cookie的工作原理吧。
 
首 先主機A使用瀏覽器上網,當主機A第一次訪問xxx網站時,當請求報文到達xxx的Web服務器時,該Web服務器將產生一個唯一識別碼(例 如:12345),並以此作為索引在它的后端數據庫中產生一個表項,並用Set-cookie:首部行和剛才產生的值為設置HTTP響應報文的首部。這樣 在HTTP響應報文的首部,我們就可以看到這樣的一個首部行——Set-cookie: 12345.
 
當主機A的瀏覽器收到該HTTP響應報文時,它會看到Set-cookie:首部,然后瀏覽器在它的本地cookie文件上加入一行,其中包括Set-cookie:首部行中的識別碼。
 
由於主機A的cookie文件已經有了用於xxx網站的表項,因此當主機A的瀏覽器繼續瀏覽xxx網站時,每請求一個Web頁面,其瀏覽器就會 從它的cookie文件中獲取到xxx網站的識別碼,並放入HTTP請求報文中cookie首部行中,即加入了首部行Cookie: 12345。
 
當xxx網站的服務器收到該包含Cookie首部行的HTTP請求報文后,服務器通過查詢后端服務器,確定cookie標識碼對應的用戶,從而可以直接知道用戶的信息(即知道確實有一個這樣的用戶,不久前登陸過該網站)。
 
注意,在cookie的方式下,xxx網站的服務器可以跟蹤主機A在該站點的活動,xxx Web站點並不需要知道主機A的用戶是誰,但是,它確切地知道用戶12345訪問了哪些頁面,按照什么順序,在什么時間。
 
簡單點來說,cookie用於標識用戶,用戶首次訪問站點時,可能需要提供一個用戶標識,但在后繼的訪問中,瀏覽器向服務器傳遞一個 cookie首部,供服務器識別該用戶。因此cookie可以在無狀態的HTTP上建立一個用戶會話層,允許服務器通過用戶與應用程序之間的會話對用戶進 行驗證。
 

Cookie的使用

 java中的response響應中加入cookie:

Cookie cookie = new Cookie("JSESSIONID", "123456"); cookie.setPath("/test"); response.addCookie(cookie);

 java中的request請求中得到cookie:

Cookie[] cookies = request.getCookies();
for (Cookie cookie : cookies) { String cookieName = cookie.getName(); String cookieValue = cookie.getValue(); System.out.println(cookieName + ", " + cookieValue); }

 

Session的介紹

1、Session的概念

使用Cookie和附加URL參數都可以將上次請求的狀態信息傳遞到下一次請求中,但是如果傳遞的狀態信息較多,將極大降低網絡傳輸效率和增大服務器端程序處理的難度。Session技術是一種會話狀態保存在服務器端的技術,它可以比喻成是醫生發給病人的病歷卡和醫院為每個病人保留的病歷檔案的結合方式。客戶端需要接收、記憶和回送Session的會話標示號,Session可以且通常是借助Cookie來傳遞會話標示號。

 

2、Session的跟蹤會話機制

Servlet API規范中定義了一個HttpSession接口,HttpSession接口定義了各種管理和操作會話狀態的方法。HttpSession對象是保持會話狀態信息的存儲結構,一個客戶端在WEB服務器端對應一個各自的HttpSession對象。Web服務器並不會在客戶端開始訪問它時就創建HttpSession對象,只有客戶端訪問某個能與客戶端開啟會話的Servlet程序是,Web應用程序才會創建一個與該客戶端對應的HttpSession對象。Web 服務器為HttpSession對象分配一個獨一無二的會話標示號,然后在響應消息中將這個會話標示號傳遞給客戶端。客戶端需要記住會話標示 號,並在后續的每次訪問請求中都把這個會話標示號傳送給Web服務器,Web服務器程序依據回傳的會話標示號就知道這次請求的客戶端發出的,從而選擇與之 對應的HttpSession對象。

 

3、Session的跟蹤機制

Web 應用程序創建與某個客戶端對應的HttpSession對象后,只要沒有超出一個限定的空閑時段,HttpSession對象就駐留在Web 服務器內存之中,該客戶端此后訪問任意的servlet程序時,它們都使用與客戶端對應的那個已存在的Httpsession對象。HttpSession 接口中專門定義了一個SetAttribute方法將對象存儲到HttpSession對象中,還定義了一個 getAttribute方法來檢索存儲在Httpsession對象中的對象,存儲進Httpsession對象中的對象可以被屬於同一個會話的各個請 求的處理程序共享。Session是實現網上商城的購物車的最佳方案,存儲在某個客戶Session中的一個集合對象就可充當給客戶的一個購物車。

 

4、Session的超時管理

Web服務器無法判斷當前的客戶端瀏覽器是否還會繼續訪問,也無法檢測客戶端瀏覽器是否關閉,所以,即使客戶已經離開或關閉了瀏覽器,Web服務器還要保留與之對應的Httpsession對象。隨着時間的推移而不斷增加新的訪問客戶端,Web服務器內存中將會因此積累起大量的不斷不在使用的Httpsession對象,並將最終導致服務器內存耗盡。Web服務器采用“超時限制”的辦法來判斷客戶端是否還在繼續訪問,如果某個客戶端在一定的時間之內沒有發出后續請求,Web服務器則認為客戶端已經停止了活動,結束與該客戶端的會話並將與之對應的Httpsession對象變成垃圾。如果客戶端瀏覽器超時后再發出訪問請求,Web服務器則認為這是一個新的會話開始,將為之創新的HttpSession對象和分配新的會話標示號。

 

session的使用

session中存儲數據:

String username = request.getParameter("username");
HttpSession session = request.getSession(); System.out.println(session.getId()); session.setAttribute("username", username);

session中得到數據:

HttpSession httpSession =  request.getSession();
String username = (String)httpSession.getAttribute("username");

 

session的原理

我們創建一個項目來分析session的原理:

一、創建一個主頁index.jsp

<form action="ContractListServlet" method="get"> username: <input type="text" name="username"/><br> <input type="submit" value="submit"> </form>

清除瀏覽器所有cookie,訪問url:http://localhost:8080/SessionTest/

詳細的請求頭部:

GET /SessionTest/ HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive

詳細的響應頭部:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=5973D26B6164CDDAFF190965C0B4677C; Path=/SessionTest/; HttpOnly
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 418
Date: Tue, 15 Mar 2016 10:25:12 GMT

保存在瀏覽器的cookie:

說明:

  • 當我們清除cookie,向tomcat服務器發送請求時,瀏覽器首先會檢查是否存在cookie文件(因為我們已經清除了cookie,所以找不到cookie)。第一次訪問,沒有cookie,直接發送請求。
  • tomcat服務器發現請求中沒有cookie頭部,於是為用戶創建一個sessionid,用作標識這個用戶的會話,並且在返回給用戶的響應中增加了cookie的頭部信息,該cookie的path為該項目的上下文/SessionTest。
  • 瀏覽器接收響應,檢查響應,發現cookie的頭部,把cookie保存起來
  • 當cookie還存在時,(也就是人們常說的再次請求)瀏覽器檢查自身保存的cookie,如果host與path都符合。那么在請求的頭部增加該符合的cookie信息
  • tomcat服務器接收到該cookie,得到cookie中的JSESSIONID的值與先前保存的sessionid做比較,如果一致,則服務器視為是同一個會話

 

二、創建ContractListServlet,以響應index.jsp的提交

String username = request.getParameter("username");
HttpSession session = request.getSession(); System.out.println(session.getId()); session.setAttribute("username", username); Cookie cookie = new Cookie("JSESSIONID", "123456"); cookie.setPath("/test"); response.addCookie(cookie); request.getRequestDispatcher("/list.jsp").forward(request, response);

填寫內容linux,點擊提交:url為http://localhost:8080/SessionTest/ContractListServlet?username=linux

詳細的請求頭部:

GET /SessionTest/ContractListServlet?username=linux HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://localhost:8080/SessionTest/
Cookie: JSESSIONID=5973D26B6164CDDAFF190965C0B4677C
Connection: keep-alive

詳細的響應頭部:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=123456; Path=/test
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 331
Date: Tue, 15 Mar 2016 10:29:25 GMT

保存的cookie:現在有兩個了

 

三、 只要我們訪問的url是這樣的形式http://localhost:8080/cookiePath/xxx/xx,瀏覽器都會攜帶cookie信息去發送請求的:

  • localhost是服務器的地 址,
  • 8080是服務器的端口,
  • cookiePath是cookie的path(圖片見上),

由於上述我們已經有了兩個cookie,它們的path分別為, /test和/SessionTest,於是測試訪問url:http://localhost:8080/test/jjii

雖然報錯404,但是cookie信息仍舊在請求當中:

GET /test/jjii HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Cookie: JSESSIONID=123456
Connection: keep-alive

 關閉瀏覽器,cookie被自動清除,所以用戶再次的請求,瀏覽器沒有找到cookie,會像上述第一次訪問一樣,請求中沒有cookie的頭部。

 

四、 我們改動ContractListServlet的代碼,在response中另外再增加兩個cookie2:以下是加了之后的代碼

Cookie cookie = new Cookie("JSESSIONID", "123456");
cookie.setPath("/test");
Cookie cookie3 = new Cookie("JSESSIONID", "123456");
cookie3.setPath("/SessionTest/");
Cookie cookie2 = new Cookie("df", "456789");
cookie2.setPath("/");

response.addCookie(cookie);
response.addCookie(cookie2);
response.addCookie(cookie3);

 再次訪問到從頭開始訪問到url:http://localhost:8080/SessionTest/ContractDetailServlet

詳細的請求頭部:

GET /SessionTest/ContractListServlet?username=linux HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://localhost:8080/SessionTest/
Cookie: JSESSIONID=3EF72ED7EC55DA676714F773E9110DB9
Connection: keep-alive

 詳細的響應頭部:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=123456; Path=/test
df=456789; Path=/
JSESSIONID=123456; Path=/SessionTest/
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 321
Date: Tue, 15 Mar 2016 12:04:00 GMT

瀏覽器中的cookie有三條:

  • name: JSESSIONID, content: 123456, path: /test
  • name: df, content: 456789, path: /
  • name: JSESSIONID, content: 123456, path: /SessionTest/

結果分析:

  • 首先瀏覽器請求時,會攜帶cookie頭部的:JSESSIONID=5DA63C198B1BBF3930A3CE7EC8613207
  • 然后在返回的時候,在響應頭部加了三個cookie信息,由於cookie3的名字與路徑都與tomcat服務器默認返回的cookie一致,所以導致了該cookie被代碼中的cookie3覆蓋

 

五、接着上面的程序,我們添加list.jsp到ContractDetailServlet的請求:http://localhost:8080/SessionTest/ContractDetailServlet

詳細的頭部請求:

GET /SessionTest/ContractDetailServlet HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://localhost:8080/SessionTest/ContractListServlet?username=linux
Cookie: JSESSIONID=123456; df=456789
Connection: keep-alive

詳細的頭部響應:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=D0ECF2D2EF3946CBBB34BC7E4A426D94; Path=/SessionTest/; HttpOnly
Content-Length: 0
Date: Tue, 15 Mar 2016 12:06:19 GMT

瀏覽器中的cookie有三條:

  • name: JSESSIONID, content: 123456, path: /test
  • name: df, content: 456789, path: /
  • name: JSESSIONID, content: D0ECF2D2EF3946CBBB34BC7E4A426D94, path: /SessionTest/

結果分析:

  • 首先瀏覽器找到匹配/SessionTest的cookie,找到了cookie2(path /)與cokie3(path /SessionTest/ ),在請求中加入這兩個cookie
  • tomcat服務器接收到請求,發現cookie的sessionid與自身保存的不一致,於是為用戶創建了一個sessionid,並把cookie加入到返回的頭部
  • 瀏覽器接收到響應的報文,把cookie保存起來,tomcat服務器發送的cookie覆蓋了瀏覽器原來的cookie3

 

以上是我個人對了session的理解,不正確的地方,還望大家斧正!


免責聲明!

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



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