【问题标题】:Why is my servlet session not persistent?为什么我的 servlet 会话不持久?
【发布时间】:2013-09-06 20:44:55
【问题描述】:

我的 servlet 按预期工作,但当我关闭浏览器(我没有删除 cookie)时,会话丢失。如何无限期地保存会话,直到我将其无效或删除我的 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 总是设置为默认的“值”。

【问题讨论】:

  • 看起来你不知道会话是什么。 -1

标签: java jsp session servlets


【解决方案1】:

您似乎完全误解了会话 cookie 的工作原理。

只要浏览器实例存在并且您在目标 URL 上触发 HTTP 请求,会话 cookie 就会存在,该目标 URL 在默认服务器端会话到期时间之前的时间内被 cookie 的path 覆盖 - 默认为 30 分钟。

一旦您关闭浏览器实例(阅读:浏览器会话),所有会话 cookie 都将消失。这是完全指定的、预期的和自然的行为。几十年来,Web 浏览器一直以这种方式工作。请注意,与 cookie 关联的 HttpSession 实例仍然存在于服务器中。如果您基于此相关答案 SessionTimeout: web.xml vs session.maxInactiveInterval() 实现 HttpSessionListener,那么您会注意到 sessionDestroyed() 方法不会在浏览器关闭时立即调用,而是仅在 30 多分钟后调用。

如果您重新打开浏览器实例并在其服务器端到期之前的时间内执行session hijacking 攻击,那么您将能够保留关联的HttpSession 实例。

另见:


现在,回到您的具体功能要求,即让 cookie 保持比浏览器会话更长的时间,这实际上非常简单:创建自己的 cookie,它不是会话 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 DB?)的键,您还可以在其中保存该myattribute 值。在每个后续请求中,只需通过 request.getCookies() 检查 cookie 的存在。这样您就可以将其与客户端相关联。如有必要,将其缓存在 HTTP 会话中,这样您就不需要检查每个 HTTP 请求。

另见:

【讨论】:

    猜你喜欢
    • 2022-11-27
    • 2013-10-29
    • 1970-01-01
    • 2012-11-20
    • 2012-03-17
    • 2013-10-22
    • 2014-09-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多