JSP Session
session 隐式对象、会话跟踪、超时与登出。
基本操作
<%
// 存
session.setAttribute("uid", 42);
session.setAttribute("cart", new java.util.ArrayList<String>());
// 取
Object uid = session.getAttribute("uid");
// 删单个
session.removeAttribute("uid");
// 会话信息
String id = session.getId();
long created = session.getCreationTime();
long last = session.getLastAccessedTime();
int timeout = session.getMaxInactiveInterval(); // 秒
%>EL 读取
<p>用户 ID:${sessionScope.uid}</p>
<p>购物车:${sessionScope.cart.size()} 件</p>
<p>会话 ID:${pageContext.session.id}</p>${uid} searches page → request → session → application. It works but is vague; ${sessionScope.uid} states the source at a glance.
登录与登出
<%-- login.jsp 提交到 doLogin.jsp --%>
<%
String user = request.getParameter("user");
String pass = request.getParameter("pass");
if (userService.check(user, pass)) {
session.setAttribute("uid", userService.idOf(user));
response.sendRedirect("home.jsp");
return;
}
%>
<p>用户名或密码错误</p><%-- logout.jsp --%>
<%
session.invalidate(); // 销毁整个会话
response.sendRedirect("login.jsp");
return;
%>Logout must call invalidate(). Removing just uid leaves other data and keeps the session id valid, so a stolen id still works.
超时配置
<session-config>
<session-timeout>30</session-timeout> <!-- 分钟 -->
</session-config><%
session.setMaxInactiveInterval(15 * 60); // 单独给这个会话设 15 分钟
%>URL 重写
<%-- 浏览器禁用 Cookie 时,把 session id 编进 URL --%>
<a href="<%= response.encodeURL("cart.jsp") %>">购物车</a>
<a href="<%= response.encodeRedirectURL("checkout.jsp") %>">结算</a>encodeURL appends ;jsessionid=... only when needed and returns the URL unchanged when cookies work. The cost is ugly URLs and leaked ids via logs or Referer, so use it only for compatibility.
基本操作
<%
// 存
session.setAttribute("uid", 42);
session.setAttribute("cart", new java.util.ArrayList<String>());
// 取
Object uid = session.getAttribute("uid");
// 删单个
session.removeAttribute("uid");
// 会话信息
String id = session.getId();
long created = session.getCreationTime();
long last = session.getLastAccessedTime();
int timeout = session.getMaxInactiveInterval(); // 秒
%>EL 读取
<p>用户 ID:${sessionScope.uid}</p>
<p>购物车:${sessionScope.cart.size()} 件</p>
<p>会话 ID:${pageContext.session.id}</p>${uid} 会按 page → request → session → application 顺序找,能找到但不够明确。用 ${sessionScope.uid} 一眼就知道数据来自会话。
登录与登出
<%-- login.jsp 提交到 doLogin.jsp --%>
<%
String user = request.getParameter("user");
String pass = request.getParameter("pass");
if (userService.check(user, pass)) {
session.setAttribute("uid", userService.idOf(user));
response.sendRedirect("home.jsp");
return;
}
%>
<p>用户名或密码错误</p><%-- logout.jsp --%>
<%
session.invalidate(); // 销毁整个会话
response.sendRedirect("login.jsp");
return;
%>登出必须 invalidate(),只 removeAttribute("uid") 不够——会话里其他数据还在,而且会话 ID 仍然有效,攻击者拿到旧 ID 还能继续用。
超时配置
<session-config>
<session-timeout>30</session-timeout> <!-- 分钟 -->
</session-config><%
session.setMaxInactiveInterval(15 * 60); // 单独给这个会话设 15 分钟
%>URL 重写
<%-- 浏览器禁用 Cookie 时,把 session id 编进 URL --%>
<a href="<%= response.encodeURL("cart.jsp") %>">购物车</a>
<a href="<%= response.encodeRedirectURL("checkout.jsp") %>">结算</a>encodeURL 会在需要时自动加上 ;jsessionid=...,Cookie 可用时原样返回。它的代价是 URL 变丑、会话 ID 可能被日志或 Referer 泄露,所以只在必须兼容时才用。