首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> JSP 程式設計 >> 關於JSP

JSP Session 內置對象完整指南:原理、用法與最佳實踐

     編輯:關於JSP

Session 核心原理

Session 是伺服器為每個客戶端瀏覽器創建的會話上下文,生命週期默認 30 分鐘無活動後失效。本質是伺服器內存中的一個 Map,鍵為屬性名,值為任意對象。

識別機制

  1. 首次訪問 → 伺服器生成唯一 JSESSIONID (UUID)
  2. 通過 Cookie (默認) 或 URL 重寫 發送給瀏覽器
  3. 後續請求攜帶 JSESSIONID,伺服器關聯對應 Session

JSP 中直接使用 session 內置對象

JSP 頁面無需聲明,直接使用 session 變量 (類型 HttpSession)。

核心 API 操作

操作方法示例
存入屬性setAttribute(String name, Object value)session.setAttribute("user", userObj);
讀取屬性getAttribute(String name)User u = (User) session.getAttribute("user");
移除屬性removeAttribute(String name)session.removeAttribute("cart");
獲取所有屬性名getAttributeNames()Enumeration names = session.getAttributeNames();
獲取 Session IDgetId()String id = session.getId();
創建時間getCreationTime()long t = session.getCreationTime();
最後訪問時間getLastAccessedTime()long t = session.getLastAccessedTime();
設置失效時間(秒)setMaxInactiveInterval(int seconds)session.setMaxInactiveInterval(30*60); // 30分
獲取失效時間(秒)getMaxInactiveInterval()int sec = session.getMaxInactiveInterval();
強制失效invalidate()session.invalidate(); // 登出調用
是否新會話isNew()if (session.isNew()) ...

典型應用場景

1. 用戶登錄狀態維持

<%-- login.jsp 驗證成功後 --%>
<%
    User user = userService.authenticate(username, password);
    if (user != null) {
        session.setAttribute("loginUser", user); // 存入用戶對象
        response.sendRedirect("index.jsp");
    } else {
        out.println("用戶名或密碼錯誤");
    }
%>

2. 權限攔截 (Filter / 頁面頂部)

<%-- 每個受保護頁面頂部 --%>
<%
    User user = (User) session.getAttribute("loginUser");
    if (user == null) {
        response.sendRedirect("login.jsp?redirect=" + URLEncoder.encode(request.getRequestURI(), "UTF-8"));
        return; // 停止執行後續頁面
    }
    // 可選:角色權限檢查
    if (!user.hasRole("ADMIN") && request.getRequestURI().contains("/admin/")) {
        response.sendError(403, "權限不足");
        return;
    }
%>

3. 購物車數據暫存

<%-- 添加商品到購物車 --%>
<%
    List cart = (List) session.getAttribute("cart");
    if (cart == null) {
        cart = new ArrayList<>();
        session.setAttribute("cart", cart);
    }
    // 添加或更新商品邏輯
    cart.add(new CartItem(productId, quantity));
%>

Session 配置與調優

1. 修改默認超時時間

方式一:web.xml (全局)

<session-config>
    <session-timeout>60</session-timeout> <!-- 分鐘 -->
</session-config>

方式二:代碼動態設置 (單個會話)

session.setMaxInactiveInterval(60 * 60); // 1 小時,單位秒

2. Session 持久化與集群同步

方案原理適用場景
Sticky Session (IP Hash)負載均衡器固定用戶到同一節點簡單、小集群、可容忍單點故障
Session 複製 (Tomcat DeltaManager)節點間廣播同步 Session 變更小集群(<8節點)、低寫入量
Redis 共享 Session (Spring Session)Session 序列化存 Redis,所有節點讀寫大型集群、微服務、高可用
資料庫持久化定時/異步寫入 DB需長期保留、審計合規

3. 內存洩漏防範

  • 及時清理:業務結束調用 removeAttribute() 或 invalidate()
  • 避免存放大對象:大文件、大集合改用臨時文件/數據庫,Session 只存引用 ID
  • 監控指標:Session 活躍數、平均大小、GC 頻率

Servlet 中獲取 Session


// 獲取現有或創建新
HttpSession session = request.getSession(true);  // 等同 request.getSession()

// 僅獲取現有,不創建
HttpSession session = request.getSession(false);
if (session != null) {
    // 已有會話
}

安全最佳實踐

  1. Cookie 安全屬性:Secure (僅 HTTPS)、HttpOnly (防 XSS)、SameSite=Strict/Lax (防 CSRF)
  2. Session ID 重生成:登錄成功後調用 session.invalidate() 再 request.getSession(true) 防固定攻擊
  3. 敏感數據加密:Session 中存儲 Token/權限而非明文密碼
  4. 超時強制登出:前端定時輪詢 / 後端攔截器檢查 session.isNew() || session.getAttribute("user")==null

常見問題排查

現象可能原因排查方向
Session 丟失/頻繁重建瀏覽器禁用 Cookie、URL 重寫失效檢查 Cookie 設置、啟用 URL 重寫 response.encodeURL()
集群環境 Session 不同步Sticky Session 失效、複製延遲遷移至 Redis 共享 Session
內存溢出 (OOM)Session 存放大對象、未清理、超時過長Heap Dump 分析、縮短超時、定時清理
並發修改異常多線程同時操作同一 SessionSession 非線程安全,加同步鎖或用 ConcurrentHashMap 替代
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved