HTTP 無狀態特性使得會話管理成為 Web 應用核心課題。Servlet API 提供 Cookie(客戶端狀態)與 HttpSession(伺服器端會話)兩大機制。本文透過兩個完整範例,系統講解從 Cookie 讀寫到購物車會話管理的實作細節。
Cookie 以「名稱/值」對形式儲存於客戶端,隨請求自動發送。Servlet 使用 javax.servlet.http.Cookie 類別封裝操作。
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class ShowCookies extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html;charset=gb2312");
PrintWriter out = resp.getWriter();
Cookie[] cookies = req.getCookies();
out.println("<html><body>");
if (cookies == null || cookies.length == 0) {
out.println("沒有 Cookies");
} else {
out.println("<table border=1><tr><th>Name</th><th>Value</th><th>Comment</th><th>Max Age</th></tr>");
for (Cookie c : cookies) {
out.println("<tr><td>" + c.getName() + "</td><td>" + c.getValue() +
"</td><td>" + c.getComment() + "</td><td>" + c.getMaxAge() + "</td></tr>");
}
out.println("</table>");
}
out.println("</body></html>");
}
}
| 方法 | 用途 |
|---|---|
new Cookie(name, value) | 建立新 Cookie |
setMaxAge(seconds) | 設定存活秒數(負值=瀏覽器關閉即刪除,0=立即刪除) |
setPath(path) | 設定 Cookie 生效路徑 |
response.addCookie(cookie) | 將 Cookie 加入回應 Header |
request.getCookies() | 取得請求中所有 Cookie 陣列 |
HttpSession 將會話狀態儲存在伺服器,客戶端僅保留 Session ID(通常透過 Cookie 或 URL 重寫傳遞)。
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
public class ShowBuy extends HttpServlet {
private static final String[] ITEMS = {"糖果", "收音機", "練習簿"};
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
HttpSession session = req.getSession(true); // 取得或建立 Session
Integer itemCount = (Integer) session.getAttribute("itemCount");
if (itemCount == null) itemCount = 0;
res.setContentType("text/html;charset=gb2312");
PrintWriter out = res.getWriter();
// 處理表單提交:將選中商品加入 Session
String[] selected = req.getParameterValues("item");
if (selected != null) {
for (String val : selected) {
int idx = Integer.parseInt(val);
itemCount++;
session.setAttribute("Item" + itemCount, ITEMS[idx]);
}
session.setAttribute("itemCount", itemCount);
}
// 輸出購物車內容
out.println("<html><body><h1>購物袋內容</h1>");
for (int i = 1; i <= itemCount; i++) {
String item = (String) session.getAttribute("Item" + i);
if (item != null) out.println(item + "<br>");
}
out.println("</body></html>");
}
}
<form action="servlet/ShowBuy" method="POST">
<input type="checkbox" name="item" value="0"> 糖果<br>
<input type="checkbox" name="item" value="1"> 收音機<br>
<input type="checkbox" name="item" value="2"> 練習簿<br>
<input type="submit" value="加入購物袋">
</form>
req.getSession(true) 等同 req.getSession();若傳 false 且不存在則回傳 null。Serializable 物件(可序列化),確保支援 Session 複製、持久化、叢集。setMaxInactiveInterval(seconds) 設定閒置逾時;invalidate() 強制銷毀。response.encodeURL(url) / encodeRedirectURL(url) 自動附加 jsessionid。Cookie 往返客戶端,切勿儲存敏感資料**(密碼、信用卡號等)。Session ID 應設定 HttpOnly、Secure 標誌,防止 XSS 與中間人攻擊。