【问题标题】:In Java servlet, cookie.getMaxAge() always returns -1在 Java servlet 中,cookie.getMaxAge() 总是返回 -1
【发布时间】:2013-01-01 17:45:28
【问题描述】:

如果我在未来设置一个带有 setMaxAge() 的 cookie,当我在后续请求中将 cookie 读回内存时,getMaxAge() 会返回 -1。我已经通过 Chrome 的设置和检查器检查了实际的 cookie,并且我可以验证过期日期确实设置为未来 60 天。

static public void setHttpCookie(HttpServletResponse response, String payload) {
    Cookie c = new Cookie(COOKIE_NAME, payload);
    c.setMaxAge(60*86400); // expire sixty days in the future
    c.setPath("/"); // this cookie is good everywhere on the site
    response.addCookie(c);
}

static public String checkForCookie(HttpServletRequest req) {
    Cookie[] cookies = req.getCookies();
    if ( cookies != null ) {
        for ( Cookie c : cookies ) {
            if ( COOKIE_NAME.equals(c.getName()) ) {
                int maxAge = c.getMaxAge();
                logger.debug("Read back cookie and it had maxAge of {}.", maxAge);
                String payload = c.getValue();
                return payload;
            }
        }
    }
    return null;
}

为什么 c.getMaxAge() 总是返回 -1?

【问题讨论】:

  • 在使用它之前尝试为 setMaxAge 声明 long(只是尝试),因为如果 cookie 设置为在浏览器关闭时销毁(这意味着负数),它只会返回 -1必须放在 setMaxAge 中才能开始)。我不确定,因为我自己没有这样做,尽管这对我来说似乎是阅读 Java 文档时的样子。
  • @BalusC:如果你这么说,那只是一个建议:)
  • @HuiZheng 谢谢...我发誓我在发帖前搜索了 StackOverflow! :-)

标签: java http servlets cookies


【解决方案1】:

浏览器不会发回诸如路径和年龄之类的 cookie 属性。它只发回名称和值。如果最大年龄已过期,则浏览器无论如何都不会发送 cookie。如果路径没有被请求 URI 覆盖,那么浏览器无论如何都不会发送 cookie。

如果您确实需要确定 cookie 的年龄在您设置 cookie 之后,那么您应该在设置 cookie 时自己记住它,例如在数据库表中,例如,与登录用户和 cookie 名称相关联。

此问题与 Java/Servlet 无关。这就是指定 HTTP cookie 的方式。在其他 Web 编程语言中,您会遇到完全相同的问题。另请参阅Wikipedia 的以下摘录(重点是我的)。

Cookie 属性

除了名称-值对之外,服务器还可以设置这些 cookie 属性:cookie 域、路径、过期时间或最长期限、安全标志和 HttpOnly 标志。 浏览器不会将 cookie 属性发送回服务器。他们只会发送 cookie 的名称-值对。浏览器使用 Cookie 属性来确定何时删除 cookie、阻止 cookie 或是否向服务器发送 cookie(名称-值对)。

您可以做的最好的事情是每次在例如登录。您可以通过再次设置完全相同的 cookie(尤其是完全相同的域/路径/名称)轻松实现此目的。它将覆盖现有的 cookie。这通常在所谓的“记住我”cookie 上以这种方式完成。

【讨论】:

  • 我允许用户切换他们的会话长度,即“记住我”,我想读取之前在 cookie 上设置的 maxAge。我将简单地将我需要的信息添加到 cookie 的有效负载中。感谢您发布我应该找到的维基百科参考。
  • 如果您尝试(重新)发明“记住我”,那么您肯定应该有一个数据库表,其中包含与用户 ID 关联的唯一自动生成的 cookie 值。只需将最后一组 maxage 存储在同一张表的新列中即可。
  • 是的,我正在(重新)实现这个广为人知的功能。具体来说,我正在实现“在这台计算机上记住我”,在这种情况下,SHORT_SESSION 或 LONG_SESSION 的状态存储在 cookie 本身中,以便为每个设备设置首选项。
  • 那么你可能会发现这个答案很有帮助,stackoverflow.com/questions/2185951/… 在 Java 中你可以使用 java.util.UUID 来生成 UUID。
  • 感谢您的指点。这正是我一直在使用的模式——用户表中的“记住我 id”列,以及两个 cookie,一个用于记住我,另一个表示会话。今天,我的实现对会话使用单个 cookie,并切换它是 LONG 还是 SHORT。这种演变使代码更加简洁明了,并且无需调用数据库。使用 UUID 可以简化我对一些随机内容的哈希处理以生成我的 id。
猜你喜欢
  • 1970-01-01
  • 2010-11-05
  • 2018-07-02
  • 1970-01-01
  • 2014-09-21
  • 2011-03-05
  • 1970-01-01
  • 2016-11-21
  • 2019-10-10
相关资源
最近更新 更多