为什么我的servlet会话不持久?

时间:2013-09-03 14:47:34

标签: java jsp session servlets

除了关闭浏览器(我没有删除cookie)之外,我的servlet按预期工作,会话丢失。如何无限期地保存会话,直到我失效或删除我的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始终设置为默认值&#34;值&#34;。

1 个答案:

答案 0 :(得分:5)

看起来你完全误解了会话cookie的工作原理。

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

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

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

另见:


现在,回到你的具体功能要求,让cookie保持活动的时间比浏览器会话长,这实际上非常简单:创建自己的cookie 会话cookie。即不要将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请求。

另见: