1. 程式人生 > >會話跟蹤之Session

會話跟蹤之Session

mes 中間 head 緩存 防止 body 時間 session 有時

  Session是服務端使用記錄客戶端狀態的一種機制,Session使用簡單,但是和Cookie相比,增加了服務器的存儲壓力【因為為了追求速度,服務器將Session放置在了內存中】。Cookie是保存在客戶端的,然而Session是保存在服務器上的。初次訪問的服務端的時候會把客戶端的信息保存起來,再次訪問的時候直接從Session中獲取即可。【客戶端初次訪問服務器的時候會自動創建Session,如果沒有生成Session則可以使用request.getSession(true)方式強制生成Session】

  但是值得註意的是,Session的使用需要Cookie的支持,因為單獨的Session還是無法知道當前訪問服務器的是否是同一個客戶端,它要根據存儲在Cookie中的JSESSIONID來進行判斷[這個Cookie是客戶端自動創建的],如果客戶端關閉了Cookie,那麽Session是沒有什麽效果的。這個時候,需要使用URL重寫的方式,將JSESSIONID直接放置在URL中,訪問服務器的時候可以直接進行解析。

  大家都知道Cookie是可以設置過期時間的,它允許設置永久有效,並且它是存儲在客戶端電腦上的,並不會占用服務器的內存。所以如果想實現"永久登錄"的話,使用Cookie是首選,並且Cookie中可以通過設置domain屬性,來達到跨域使用[多個窗口公用Cookie]。然而Session需要占用太多的服務器內存,並且不支持跨域使用,不同的窗口訪問客戶端都會創建一個Session,Session過多會造成內粗溢出【當然服務端也有相應的措施應對溢出,那就是通過設置Session的有效期,有效期到達之後就會將Session清除】

  但是Session中可以存儲多種類型的數據,不僅能存儲String還可以直接存儲一個javaBean對象,然而Cookie中僅僅能存儲String。並且Session的安全性要比Cookie的安全性高的多,因為它是存儲在服務器上的,外部人員不能輕易更改,然而Cookie是保存在客戶端電腦上的,隨時都有可能被更改,雖然說可以將信息加密,然後存儲在Cookie中,但是跟Session相比,安全性還是比較低的。

  所以通常"會話跟蹤"的時候,通常是兩者配合使用以達到想要的效果!

一:代碼演示:利用Session存儲用戶信息,然後在歡迎界面獲取用戶信息【此處登錄界面和歡迎界面是一個】

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 4 <html>
 5
<head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <title>演示Session的使用</title> 8 </head> 9 <body> 10 <!-- 利用JSP的行為創建一個User實例 ,存放在默認的page域中--> 11 <jsp:useBean id="user" class="cn.woo.entity.User" scope="page"></jsp:useBean> 12 <jsp:setProperty property="username" name="user" value="woo"/> 13 <jsp:setProperty property="password" name="user" value="123456"/> 14 15 <%! 16 //定義要顯示的錯誤提示信息 17 String message = ""; 18 //登錄標誌 19 boolean login = false; 20 %> 21 22 <!-- 接收請求 --> 23 <% 24 System.out.println(request.getMethod()); 25 if(request.getMethod().equalsIgnoreCase("post")){ 26 request.setCharacterEncoding("utf-8"); 27 response.setCharacterEncoding("utf-8"); 28 29 //獲取用戶名和密碼 30 String username = request.getParameter("username"); 31 String password = request.getParameter("password"); 32 33 //驗證用戶名和密碼是否正確 34 if((username!=null && !username.isEmpty()) && (password!=null && !password.isEmpty())){ 35 if((username.equals(user.getUsername())) && (password.equals(user.getPassword()))){ 36 login = true;
37                     //利用Session記錄用戶信息
38                     session.setAttribute("userInfo",user);
39                     //重定向至該頁面,添加參數System.currentTimeMillis(),防止客戶端緩存頁面數據
40                     response.sendRedirect(request.getRequestURI()+"?"+System.currentTimeMillis());
41                     return;
42                 }else{
43                     message = "用戶名密碼錯誤請重新登錄";
44                 }
45             }else{
46                 message = "用戶名和密碼不能為空";
47             }
48         }else{
49             message = "請先登錄";
50         }
51     %>
52     
53     <%
54         if(login){
55             %>    
56                 <!-- 利用EL表達式獲取存放在Session中的userInfo -->
57                 <p style="width:200px;height:200px;border:1px solid black;margin:100px auto;line-height:200px;text-align:center;">歡迎:<span>${userInfo.username}</span></p>
58             <%
59         }else{
60             %>
61                 <!-- 登錄界面 -->
62                 <form action="<%=request.getRequestURI()+"?"+System.currentTimeMillis()%>" method="post">
63                     <table>
64                         <tr>
65                             <td colspan="2"><%=message %></td>
66                         </tr>
67                         <tr>
68                             <td align="right"><label for="name">用戶名:</label></td>
69                             <td><input type="text" name="username" id="name"></td>
70                         </tr>
71                         <tr>
72                             <td align="right"><label for="pwd">密碼:</label></td>
73                             <td><input type="password" name="password" id="pwd"></td>
74                         </tr>
75                         <tr>
76                             <td colspan="2"><input type="submit" value="登錄"></td>
77                         </tr>
78                     </table>
79                 </form>
80             <%
81         }
82     %>
83 </body>
84 </html>

下方圖片就是服務端需要的Cookie,可以看到Cookie中存放了一個JSESSIONID:

技術分享圖片

二:有時候客戶端不支持Cookie,或者說客戶端禁用Cookie,這個時候可以使用URL重寫的方式,添加JSESSIONID到URL中,一並發送到服務器:

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 4 <html>
 5 <head>
 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 7 <title>演示Session的使用</title>
 8 </head>
 9 <body>
10     <!-- 利用JSP的行為創建一個User實例 ,存放在默認的page域中-->
11     <jsp:useBean id="user" class="cn.woo.entity.User" scope="page"></jsp:useBean>
12     <jsp:setProperty property="username" name="user" value="woo"/>
13     <jsp:setProperty property="password" name="user" value="123456"/>
14         
15     <%!
16         //定義要顯示的錯誤提示信息
17         String message = "";
18         //登錄標誌
19         boolean login = false;
20     %>
21     
22     <!-- 接收請求 -->
23     <%    
24         System.out.println(request.getMethod());
25         if(request.getMethod().equalsIgnoreCase("post")){
26             request.setCharacterEncoding("utf-8");
27             response.setCharacterEncoding("utf-8");
28             
29             //獲取用戶名和密碼
30             String username = request.getParameter("username");
31             String password = request.getParameter("password");
32             
33             //驗證用戶名和密碼是否正確
34             if((username!=null && !username.isEmpty()) && (password!=null && !password.isEmpty())){
35                 if((username.equals(user.getUsername())) && (password.equals(user.getPassword()))){
36                     login = true;
37                     //設置Session的有效期,單位為s
38                     session.setMaxInactiveInterval(30*60);
39                     //利用Session記錄用戶信息
40                     session.setAttribute("userInfo",user);
41                     //重定向至該頁面,添加參數,放置客戶端緩存頁面數據
42                     //response.sendRedirect(request.getRequestURI()+"?"+System.currentTimeMillis());
43                     //客戶端不支持Cookie或者關閉Cookie的時候使用該方式進行URL的重寫
44                     response.encodeRedirectURL(request.getRequestURI()+"?"+System.currentTimeMillis());
45                     return;
46                 }else{
47                     message = "用戶名密碼錯誤請重新登錄";
48                 }
49             }else{
50                 message = "用戶名和密碼不能為空";
51             }
52         }else{
53             message = "請先登錄";
54         }
55     %>
56     
57     <%
58         if(login){
59             %>    
60                 <!-- 利用EL表達式獲取存放在Session中的userInfo -->
61                 <p style="width:200px;height:200px;border:1px solid black;margin:100px auto;line-height:200px;text-align:center;">歡迎:<span>${userInfo.username}</span></p>
62             <%
63         }else{
64             %>
65                 <!-- 登錄界面 -->
66                 <!-- 客戶端不支持Cookie或者關閉Cookie的時候使用該方式進行URL的重寫  
67                      response.encodeURL(request.getRequestURI()+"?"+System.currentTimeMillis())
68                 -->
69                 <form action="<%=response.encodeURL(request.getRequestURI()+"?"+System.currentTimeMillis()) %>" method="post">
70                     <table>
71                         <tr>
72                             <td colspan="2"><%=message %></td>
73                         </tr>
74                         <tr>
75                             <td align="right"><label for="name">用戶名:</label></td>
76                             <td><input type="text" name="username" id="name"></td>
77                         </tr>
78                         <tr>
79                             <td align="right"><label for="pwd">密碼:</label></td>
80                             <td><input type="password" name="password" id="pwd"></td>
81                         </tr>
82                         <tr>
83                             <td colspan="2"><input type="submit" value="登錄"></td>
84                         </tr>
85                     </table>
86                 </form>
87             <%
88         }
89     %>
90 </body>
91 </html>

點擊登錄的時候會清晰的看到URL的內容變化,中間包含jsessionid

http://localhost:8080/JSPDemo/session.jsp;jsessionid=D01238B61D0544108E0C04AA5E17EE6C?1534577455038

通常Cookie被禁用的方式很常見,所以一般都是禁用Cookie然後,直接同意采用URL重寫的方式進行Session的使用:

【Session中禁用Cookie的方式】:

技術分享圖片

會話跟蹤之Session