除了关闭浏览器(我没有删除 cookie)之外,我的 servlet 正在按预期工作, session 丢失。如何无限期地保存 session ,直到我使它失效或删除我的 cookie?
@WebServlet(name="ServletOne", urlPatterns={"/", "/ServletOne"})
public class ServletOne extends HttpServlet {
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession(true);
String newValue = request.getParameter("newValue");
if (session.isNew()) {
session = request.getSession(true);
session.setAttribute("myAttribute", "value");
}
if (newValue != null)
session.setAttribute("myAttribute", newValue);
RequestDispatcher rd = request.getRequestDispatcher("test.jsp");
rd.forward(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
我的 JSP:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
val == <c:out value="${myAttribute}"></c:out><br>
<form action="ServletOne" method="POST">
<input type="text" name="newValue" />
<input type="submit" />
</form>
</body>
</html>
如果我关闭浏览器并重新打开它,myAttribute
始终设置为默认“值”。
最佳答案
看来您完全误解了 session cookie 的工作原理。
只要浏览器实例存在, session cookie 就会存在,并且您在默认服务器端 session 过期时间之前的时间内在 cookie 的 path
覆盖的目标 URL 上触发 HTTP 请求 - 这是默认值到 30 分钟。
一旦关闭浏览器实例(阅读:浏览器 session ),所有 session cookie 都将消失。这是完全指定的、预期的和自然的行为。几十年来,Web 浏览器一直以这种方式工作。请注意,与 cookie 关联的 HttpSession
实例仍然存在于服务器中。如果您根据此相关答案 SessionTimeout: web.xml vs session.maxInactiveInterval() 实现 HttpSessionListener
,然后您会注意到 sessionDestroyed()
方法不会在浏览器关闭时立即调用,而是在 30 多分钟后才会调用。
如果您重新打开浏览器实例并执行 session hijacking在服务器端到期之前的时间内发起攻击,那么您将能够保留关联的 HttpSession
实例。
另见:
现在,回到让 cookie 保持 Activity 时间超过浏览器 session 的具体功能需求,这实际上非常简单:创建您自己的 cookie,它不是 session cookie。 IE。不要设置 cookie 的 maxAge
为 -1
(默认值),而是将其设置为以秒为单位的指定时间。
Cookie cookie = new Cookie("someCommonName", "someUniqueValue");
cookie.setMaxAge(ageInSeconds); // Use e.g. 2952000 for 30 days.
response.addCookie(cookie);
someUniqueValue
又可以类似于 java.util.UUID
。您可以将该值用作某些数据存储系统(SQL 数据库?)的键,您还可以在其中保存该 myattribute
值。在每个后续请求中,只需通过 request.getCookies()
检查 cookie 是否存在。这样您就可以将它与客户端相关联。如有必要,将其缓存在 HTTP session 中,这样您就无需检查每个 HTTP 请求。
另见:
关于java - 为什么我的 servlet session 不持久?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18595272/