HTTP 是無狀態協定,HttpSession 提供伺服器端儲存機制,跨請求識別同一使用者。JSP 透過隱含物件 session 直接操作。
<%@ page session="true" %>)<%@ page session="false" %>request.getSession() (自動建立) / request.getSession(false) (不建立)| 方法 | 說明 |
|---|---|
setAttribute(name, value) | 儲存物件 (任何可序列化類別) |
getAttribute(name) | 取得物件,不存在回傳 null |
removeAttribute(name) | 移除指定屬性 |
getAttributeNames() | 列舉所有屬性名稱 |
getId() | 取得 Session ID (JSESSIONID) |
getCreationTime() | 建立時間 (毫秒) |
getLastAccessedTime() | 最後存取時間 |
getMaxInactiveInterval() | 取得逾時秒數 |
setMaxInactiveInterval(seconds) | 設定逾時秒數 (負數 = 永不逾時) |
invalidate() | 立即失效,移除所有屬性 |
isNew() | 是否為新建立 (客戶端尚未收到 Cookie) |
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.util.Date" %>
<%
// 讀取或初始化計數器
Integer visitCount = (Integer) session.getAttribute("visitCount");
if (visitCount == null) visitCount = 0;
visitCount++;
session.setAttribute("visitCount", visitCount);
// 模擬登入用戶
String userName = (String) session.getAttribute("userName");
if (userName == null) {
userName = "訪客_" + session.getId().substring(0, 6);
session.setAttribute("userName", userName);
}
%>
<!DOCTYPE html>
<html><head><meta charset="UTF-8"><title>Session Demo</title></head>
<body>
<h2>Session 資訊</h2>
<table border="1" cellpadding="5">
<tr><th>屬性</th><th>值</th></tr>
<tr><td>Session ID</td><td><%= session.getId() %></td></tr>
<tr><td>建立時間</td><td><%= new Date(session.getCreationTime()) %></td></tr>
<tr><td>最後存取</td><td><%= new Date(session.getLastAccessedTime()) %></td></tr>
<tr><td>逾時設定</td><td><%= session.getMaxInactiveInterval() %> 秒</td></tr>
<tr><td>是否新 Session</td><td><%= session.isNew() %></td></tr>
<tr><td>用戶名稱</td><td><%= userName %></td></tr>
<tr><td>訪問次數</td><td><%= visitCount %></td></tr>
</table>
<p><a href="logout.jsp">登出 (銷毀 Session)</a></p>
</body></html>
<%-- logout.jsp --%>
<%
session.invalidate(); // 移除所有屬性,Session 失效
response.sendRedirect("login.jsp");
%>
session.setMaxInactiveInterval(30 * 60); // 30 分鐘
<session-config> <session-timeout>30</session-timeout> <!-- 分鐘 --> </session-config>
<Context sessionCookiePath="/"> <Manager pathname="" /> <!-- 關閉重啟保留 --> </Context>
| 機制 | 原理 | 優缺點 |
|---|---|---|
| Cookie (預設) | JSESSIONID 存於瀏覽器 Cookie | 最通用,但使用者可關閉 Cookie |
| URL 重寫 | URL 附加 ;jsessionid=xxx | 支援無 Cookie 環境,但 URL 醜陋、需所有連結處理 |
| SSL Session | 利用 SSL 會話 ID | 安全但配置複雜,較少用 |
啟用 URL 重寫:所有輸出 URL 使用 response.encodeURL() / response.encodeRedirectURL()。
<dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency> # application.properties spring.session.store-type=redis spring.redis.host=localhost spring.redis.port=6379
無需修改程式碼,原本 session.setAttribute() 自動儲存至 Redis。
Set-Cookie: JSESSIONID=...; Secure; HttpOnly; SameSite=Strictrequest.changeSessionId() (Servlet 3.1+) 防止 Session Fixation