Servlet Session
session概念
定義: session 是存儲在服務器上的文本文件,並保留了用戶的各種跟蹤信息
作用: 會話保持,如完成用戶的登錄與狀態保持,因爲在服務器端,所以相對安全一些
Servlet 操作session方法
HttpSession 對象
Servlet 還提供了 HttpSession 接口,該接口提供了一種跨多個頁面請求或訪問網站時識別用戶以及存儲有關用戶信息的方式。
Servlet 容器使用這個接口來創建一個 HTTP 客戶端和 HTTP 服務器之間的 session 會話。會話持續一個指定的時間段,跨多個連接或頁面請求。
我們可以通過調用 HttpServletRequest 的公共方法 getSession() 來獲取 HttpSession 對象,需要在向客戶端發送任何文檔內容之前調用 request.getSession()
1、服務器如何判斷客戶端發送過來的請求是屬於同一個會話?
答:用Session id區分,Session id相同的即認爲是同一個會話,在Tomcat中Session id用JSESSIONID表示;
2、服務器、客戶端如何獲取Session id?Session id在其之間是如何傳輸的呢?
答:服務器第一次接收到請求時,開闢了一塊Session空間(創建了Session對象),同時生成一個Session id,並通過響應頭的Set-Cookie:“JSESSIONID=XXXXXXX”命令,向客戶端發送要求設置cookie的響應;
客戶端收到響應後,在本機客戶端設置了一個JSESSIONID=XXXXXXX的cookie信息,該cookie的過期時間爲瀏覽器會話結束;
接下來客戶端每次向同一個網站發送請求時,請求頭都會帶上該cookie信息(包含Session id);
然後,服務器通過讀取請求頭中的Cookie信息,獲取名稱爲JSESSIONID的值,得到此次請求的Session id;
ps:服務器只會在客戶端第一次請求響應的時候,在響應頭上添加Set-Cookie:“JSESSIONID=XXXXXXX”信息,接下來在同一個會話的第二第三次響應頭裏,是不會添加Set-Cookie:“JSESSIONID=XXXXXXX”信息的;
而客戶端是會在每次請求頭的cookie中帶上JSESSIONID信息;
代碼示例
如何使用 HttpSession 對象獲取 session 會話創建時間和最後訪問時間。如果不存在 session 會話,我們通過請求創建一個新的 session 會話
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
public class HelloServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 如果不存在 session 會話,則創建一個 session 對象
HttpSession session = request.getSession(true);
// 獲取 session 創建時間
Date createTime = new Date(session.getCreationTime());
// 獲取該網頁的最後一次訪問時間
Date lastAccessTime = new Date(session.getLastAccessedTime());
String title = "歡迎回來";
String visitCountKey = new String("visitCount");
Integer visitCount = new Integer(0);
String userIDKey = new String("userID");
String userID = new String("abcd");
// 檢查網頁上是否是新的訪問者
if (session.isNew()) {
title = "歡迎來到我的網站";
session.setAttribute(userIDKey, userID);
} else {
visitCount = (Integer) session.getAttribute(visitCountKey);
visitCount++;
userID = (String) session.getAttribute(userIDKey);
}
session.setAttribute(visitCountKey, visitCount);
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
String docType = "<!doctype html>\n";
out.println(docType + "<html>\n" +
"<head><title>" + title + "</title></head>\n" +
"<body>\n" +
"<h1>" + title + "</h1>\n" +
"<h2> Session 信息 </h2>" +
"<p>" +
"ID: " + session.getId() + "<hr/><br/>" +
"Create Time: " + createTime + "<hr/><br/>" +
"Time of Last Access: " + lastAccessTime + "<hr/><br/>" + "User ID: " + userID + "<hr/><br/>" +
"Number of visits: " + visitCount + "<hr/><br/>" +
"</p>" + "</body>" +
"</html>");
}
}
session持久化
一般情況下,session是直接存儲在指定服務器的內存中的,一般使用夠了,但是在集羣場景當中,可能需要通過session共享,來保證用戶在不同的服務器上都可以得到認證。所以我們一般可以將用戶的session信息統一保存在後端的數據庫服務器中[比如,mysql/redis/memcache等],從而達到不同服務器間session的共享。可以簡單理解:將session保存在服務器數據庫或者文件中的行爲稱之爲session持久化