關於servlet會話跟蹤,一搜都能搜出不少。我也難免落入俗套,也總結了一把。但願我所總結的知識儘可能是知識海洋裏的一汪清泉。能幫助到我本身和哪怕一我的,那也是值得的。html
咱們知道,http協議是個無狀態的協議,所謂無狀態就是指此時刻咱們的狀態是保持鏈接,下一刻咱們的狀態可能就是斷開鏈接,狀態是不穩定的,這就致使不少用戶在上網時遇到問題,好比購物,我添加幾回商品到購物車,若是沒有會話跟蹤,那麼這些商品是沒辦法添加到一個購物車中的。再好比登陸,每次訪問同一個網站時,我每次都要輸入用戶名和密碼,在同一個網站中,每一個界面都要輸入一次用戶名和密碼才能繼續作其餘事情。這就很尷尬了,因此,有會話跟蹤技術的機制就誕生了。java
維持會話技術的4大法寶web
cookie在瀏覽器容許使用的狀態下,當客戶請求服務器後,服務器會發送一個含有惟一的sessionID的cookie給客戶端,並保存到客戶端本地,下次客戶端再和服務器交互時,經過在request頭中加入cookie中的信息,服務器能辨識出客戶身份,從而維持會話。redis
在<input>中添加一個隱藏的字段,好比這樣:chrome
<input type="hidden" name="sessionid" value="12345">
那麼在提交表單時,會把這個隱藏的名爲sessionID的值爲12345的域提交在GET或者POST數據中,服務器收到個人請求後,會給一個客戶端一個cookie中有瀏覽器
Cookie:JSESSIONID=E6047C8DB41EEA107256ECB443640C49
每次向服務器請求時,就帶着個人JSESSIONID,服務器會認識個人JSESSIONID給我發送我須要的請求。緩存
在每一個 URL 末尾追加一些額外的數據來標識 session 會話,服務器會把該 session 會話標識符與已存儲的有關 session 會話的數據相關聯。session 會話標識符被附加爲 sessionid=12345,標識符可被 Web 服務器訪問以識別客戶端。tomcat
介紹完上面3個,下面是隆重登場的主角了。服務器
每個事物產生都有它的做用,session也是,session由servlet容器產生,是一種會話跟蹤技術,能解決用戶在登陸或者購物時多頁面請求或存儲相關用戶信息。cookie
好比這麼個場景:你在打開淘寶,而後看到個想買的商品後,你點擊當即購買,可是這時候會跳到登陸那個新的界面,而後你登陸以後,什麼事都不用作,再次回到那個商品購買界面刷新下,你就發現這時候你再買這個商品就能夠了。這就是session的做用。
多說一句:上面說到的cookie,其中就包含有session的ID,session是藉助cookie來實現會話跟蹤的,因此,若是cookie被刪或者禁用的話,session這個會話跟蹤技術也就沒法使用了。
session的前世此生:
這是後來補的,由於以前對session的理解有誤差,因此這裏糾正下。由問答形式給出。
session由誰建立,怎麼建立?
session由服務器端建立,建立方式:HttpSession session = request.getSession(true)。
session在哪保存?
session保存在服務器端,session建立好會由Tomcat的StandardManager類將session存儲在服務器內存中,也能夠持久化到DB,file,redis中。
session既然由服務器建立,那麼在Tomcat中如何建立的?
在tomcat服務器中由ManagerBase類提供建立方法:隨機數+時間+jvmid。
session有哪些接口?
建立好session後就可使用session的API了,API在下面給出。
客戶端會保存session嗎?
客戶端(瀏覽器端)是不會保存session的,session在服務器端保存,客戶端只保存一個sessionid到cookie中,而不會保存session。
session最終是怎麼銷燬的?
經過session.invalidate、超時、關閉服務器中三者之一。單純關閉瀏覽器session不會消失,由於session不在瀏覽器端保存,而在服務器端。
session的API以下:
public Object getAttribute(String name)
該方法返回在該 session 會話中具備指定名稱的對象,若是沒有指定名稱的對象,則返回 null。
public Enumeration getAttributeNames()
該方法返回 String 對象的枚舉,String 對象包含全部綁定到該 session 會話的對象的名稱。
public long getCreationTime()
該方法返回該 session 會話被建立的時間,自格林尼治標準時間 1970 年 1 月 1 日午夜算起,以毫秒爲單位。
public String getId()
該方法返回一個包含分配給該 session 會話的惟一標識符的字符串。
public long getLastAccessedTime()
該方法返回客戶端最後一次發送與該 session 會話相關的請求的時間自格林尼治標準時間 1970 年 1 月 1 日午夜算起,以毫秒爲單位。
public int getMaxInactiveInterval()
該方法返回 Servlet 容器在客戶端訪問時保持 session 會話打開的最大時間間隔,以秒爲單位。
public void invalidate()
該方法指示該 session 會話無效,並解除綁定到它上面的任何對象。
public boolean isNew()
若是客戶端還不知道該 session 會話,或者若是客戶選擇不參入該 session 會話,則該方法返回 true。
public void removeAttribute(String name)
該方法將從該 session 會話移除指定名稱的對象。
public void setAttribute(String name, Object value)
該方法使用指定的名稱綁定一個對象到該 session 會話。
public void setMaxInactiveInterval(int interval)
該方法在 Servlet 容器指示該 session 會話無效以前,指定客戶端請求之間的時間,以秒爲單位。
下面說的是session和session的ID,不一樣的訪問者對不一樣的session和sessionID,
舉例以下,一個test.html,一個testSession.java,一個google chrome,一個火狐瀏覽器。
test.html文件以下:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Test</title> 6 </head> 7 <body> 8 <form action="http://127.0.0.1:8081/HelloServlet/testSession" method="post"> 9 <input type="text" name="username" /> 10 <input type="submit" /> 11 </form> 12 </body> 13 </html>
testSession.java文件以下(.java文件使用的是eclipse下建立的servlet文件)
1 package com.hundsun.vivizhang.servlet; 2 3 import java.io.IOException; 4 5 import java.io.PrintWriter; 6 import java.util.Date; 7 8 import javax.jws.WebService; 9 import javax.servlet.ServletException; 10 import javax.servlet.annotation.WebServlet; 11 import javax.servlet.http.HttpServlet; 12 import javax.servlet.http.HttpServletRequest; 13 import javax.servlet.http.HttpServletResponse; 14 import javax.servlet.http.HttpSession; 15 16 @WebServlet("/testSession") 17 public class testSession extends HttpServlet{ 18 private static final long serialVersionUID = 1L; 19 20 /** 21 * @see HttpServlet#HttpServlet() 22 */ 23 public testSession() { 24 super(); 25 // TODO Auto-generated constructor stub 26 } 27 28 /** 29 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse 30 * response) 31 */ 32 protected void doGet(HttpServletRequest request, HttpServletResponse response) 33 throws ServletException, IOException { 34 // Create a session object if it is already not created. 35 HttpSession session = request.getSession(true); 36 // Get session creation time. 37 Date createTime = new Date(session.getCreationTime()); 38 // Get last access time of this web page. 39 Date lastAccessTime = 40 new Date(session.getLastAccessedTime()); 41 42 String title = "Welcome Back to my website"; 43 Integer visitCount = new Integer(0); 44 String visitCountKey = new String("visitCount"); 45 String userIDKey = new String("userID"); 46 String userID = new String("ABCD"); 47 48 // Check if this is new comer on your web page. 49 if (session.isNew()){ 50 title = "Welcome to my website"; 51 session.setAttribute(userIDKey, userID); 52 } else { 53 visitCount = (Integer)session.getAttribute(visitCountKey); 54 visitCount = visitCount + 1; 55 userID = (String)session.getAttribute(userIDKey); 56 } 57 session.setAttribute(visitCountKey, visitCount); 58 59 // Set response content type 60 response.setContentType("text/html"); 61 PrintWriter out = response.getWriter(); 62 63 String docType = 64 "<!doctype html public \"-//w3c//dtd html 4.0 " + 65 "transitional//en\">\n"; 66 out.println(docType + 67 "<html>\n" + 68 "<head><title>" + title + "</title></head>\n" + 69 "<body bgcolor=\"#f0f0f0\">\n" + 70 "<h1 align=\"center\">" + title + "</h1>\n" + 71 "<h2 align=\"center\">Session Infomation</h2>\n" + 72 "<table border=\"1\" align=\"center\">\n" + 73 "<tr bgcolor=\"#949494\">\n" + 74 " <th>Session info</th><th>value</th></tr>\n" + 75 "<tr>\n" + 76 " <td>id</td>\n" + 77 " <td>" + session.getId() + "</td></tr>\n" + 78 "<tr>\n" + 79 " <td>Creation Time</td>\n" + 80 " <td>" + createTime + 81 " </td></tr>\n" + 82 "<tr>\n" + 83 " <td>Time of Last Access</td>\n" + 84 " <td>" + lastAccessTime + 85 " </td></tr>\n" + 86 "<tr>\n" + 87 " <td>User ID</td>\n" + 88 " <td>" + userID + 89 " </td></tr>\n" + 90 "<tr>\n" + 91 " <td>Number of visits</td>\n" + 92 " <td>" + visitCount + "</td></tr>\n" + 93 "</table>\n" + 94 "</body></html>"); 95 } 96 97 /** 98 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse 99 * response) 100 */ 101 protected void doPost(HttpServletRequest request, HttpServletResponse response) 102 throws ServletException, IOException { 103 // TODO Auto-generated method stub 104 doGet(request, response); 105 } 106 }
此處不用配置web.xml文件。
實驗開始,先清掉瀏覽器的緩存,而後在瀏覽器中輸入 localhost:8080/HelloServlet/test.html ,個人圖中用的是127.0.0.1的環路地址,是同樣的哈。
輸入完後,打開chrome的F12按鍵,敲擊回車,訪問到頁面,獲得的不含cookie的F12中的截圖(圖1)是這樣的。
圖1
而後輸入一些信息,點擊提交後,F12調試頁面是這樣的(圖2)。
圖2
點擊提交後跳轉到這個界面(圖3)
圖3
而後就能獲得下面的結論:
(1)同一瀏覽器相同學口刷新後,訪問的是同一sessionID,如圖4所示,刷新1次,顯示訪問次數爲2.
(2)同一瀏覽器不一樣窗口訪問,訪問的是同一sessionID,如圖4所示,開兩個窗口,可是sessionId仍然是E04B...065.
圖4
(3)同一瀏覽器關閉後再次訪問也不是同一session,如圖5所示,切換到firefox後id和visitCount都不一樣了。
圖5
(4)不一樣的瀏覽器訪問是不一樣session和sessionID。如圖6所示。
圖6
這個故事說的是會話跟蹤的技術,之後在使用Servlet時,要學會使用,這是一個很是重要的技術,可是也聽到有反對使用cookie的,這些都不是重點,重點是這個技術是如今web開發必不可少的。