將 Java 物件儲存在 HttpSession 中
1. 引言
在開發基於 Java 的 Web 應用程式時,我們經常需要在 HTTP 請求之間維護使用者相關資料。 HTTP 是一種無狀態協議,不會在請求之間保存任何資訊。這意味著每個 HTTP 請求都是獨立的,並且事先不知道同一會話中其他請求的資訊。
在本教程中,我們將詳細討論與HttpSession介面相關的基本概念。我們也將討論如何使用該介面提供的關鍵方法(例如setAttribute(), getAttribute()和removeAttribute()來儲存、擷取和刪除Java物件。
2. 什麼是HttpSession ?
HttpSession介面是javax.servlet.http套件的一部份。它用於在多個 HTTP 請求之間將用戶資料儲存在伺服器端。 HTTP 是一個無狀態協定。 HttpSession 透過為每個使用者提供一個唯一的會話,彌補了 HTTP 無狀態性與在伺服器端儲存使用者資料之間的差距。
Servlet 容器負責建立會話,並使用儲存在客戶端瀏覽器中名為JSESSIONID的唯一會話 ID(以 cookie 形式存在)來追蹤會話。我們可以使用HttpServletRequest物件的getSession()方法從任何 Servlet 存取會話。下面我們來看一個取得會話的範例:
HttpSession session = request.getSession();
如果已經建立了會話, request.getSession()方法將傳回目前活動會話。否則,它將創建一個全新的會話。我們也可以傳遞參數 `false`: request.getSession(false) 。這樣我們就可以在不建立新會話的情況下取得現有會話。取得會話物件後,我們就可以開始在其中儲存資料了。
3. 將 Java 物件儲存在HttpSession中
Java 物件透過HttpSession介面提供的setAttribute()方法儲存在會話中。此方法接受兩個參數:一個String鍵和一個要儲存的物件。這樣就可以輕鬆地將任何 Java 物件與一個鍵關聯起來,以便稍後檢索。
假設我們有一個User類,並且想要將已登入使用者的資料儲存在會話中。首先,以下是我們的簡單User類別:
public class User implements Serializable {
private String username;
private String email;
public User(String username, String email) {
this.username = username;
this.email = email;
}
public String getUsername() { return username; }
public String getEmail() { return email; }
}
現在,讓我們來看看如何在 servlet 的會話中儲存此物件的實例:
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
User user = new User("john_doe", "[email protected]");
HttpSession session = request.getSession();
session.setAttribute("loggedInUser", user);
}
在這個範例中,我們首先建立一個包含使用者名稱和郵箱地址的新User物件。然後,我們呼叫request.getSession()來取得目前會話。之後,我們使用session.setAttribute(“loggedInUser”, user)將該物件儲存在鍵為“loggedInUser”的位置。從現在開始,同一會話中的任何 servlet 或 JSP 都可以使用該鍵存取此物件。
4. 從HttpSession檢索 Java 對象
**一旦我們將物件儲存到會話中,就需要一種可靠的機制在下次請求中存取它。 `getAttribute getAttribute()函數正是為此而生的**。它根據setAttribute()函數中使用的鍵傳回對應的物件。因此,它使我們能夠在整個會話期間存取用戶資料。
在前一個範例的基礎上,以下是如何在另一個 servlet 中擷取已儲存的User物件:
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession(false);
private static final Logger logger = LoggerFactory.getLogger(StoreSessionServlet.class);
if (session != null) {
User user = (User) session.getAttribute("loggedInUser");
if (user != null) {
logger.info("Welcome back, " + user.getUsername());
} else {
logger.info("No user found in session.");
}
} else {
logger.info("No active session found.");
}
}
首先,我們呼叫request.getSession(false)來取得目前會話,避免意外開啟新會話。然後,我們透過session.getAttribute(“loggedInUser”)取得儲存的對象,並將其強制轉換為User 。關鍵在於始終檢查它是否為空。例如,會話可能已逾時,或者我們可能尚未設定該屬性。因此,簡單的空值檢查是防止程式碼出現NullPointerException異常的常見做法。
5. 從HttpSession移除對象
在某些時候,我們需要清理不再需要的會話資料。例如,當使用者登出時,我們會清除使用者的詳細資料;或清除某個特定屬性。 HttpSession HttpSession提供了兩種方法來實現這一點: removeAttribute() ,用於刪除特定物件;以及invalidate() ,用於清除整個會話。
以下是我們在實踐中如何使用這兩種方法:
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession(false);
if (session != null) {
session.removeAttribute("loggedInUser");
session.invalidate();
}
}
在這個範例中,我們首先透過request.getSession(false)來取得現有會話。然後,我們呼叫session.removeAttribute(“loggedInUser”)刪除之前儲存的User對象,同時保留會話中的其他所有資料。 `session.invalidate session.invalidate()會移除整個會話,清除記憶體中會話內的所有資料。此外,新增空值檢查非常重要,以避免在沒有活動會話時出現錯誤。
6. 結論
本文討論如何使用三個基本操作在HttpSession中管理 Java 對象: setAttribute用於將對象放入會話, getAttribute用於從會話中檢索對象, removeAttribute用於從會話中清除特定對象。如您所見,我們可以很好地控制儲存在會話中的對象,並利用這一點,使用無狀態的 HTTP 協定建立有狀態、使用者感知的 Web 應用程式。
除了基礎知識之外,我們也了解了謹慎處理會話的重要性。我們在檢索屬性時會進行空值檢查,並在使用者登出時呼叫*`invalidate()`*函數,以防止過期資料殘留在伺服器上。有了這些基本要素,我們就能應付實際的會話管理挑戰,並建立既健全又安全的 Java Web 應用程式。
和往常一樣,完整的程式碼可以在Github上找到。