【问题标题】:Best option for Session management in JavaJava 会话管理的最佳选择
【发布时间】:2010-12-14 14:19:57
【问题描述】:

Java 中管理会话的最佳方式。我听说 cookie 不是可靠的选择,因为它们存储在浏览器中,以后可以访问?它是否正确?如果可能,请通过编码示例给出答案。

哪个是最好的:

  • URL 重写:服务器会在 URL 链接的末尾添加一个额外的参数
  • 表单中的隐藏参数:服务器将在 HTML 中的每个表单中添加一个附加参数
  • cookie:服务器会要求浏览器维护一个cookie。

【问题讨论】:

标签: java session servlets cookies url-rewriting


【解决方案1】:

会话管理(客户端识别、cookie 处理、保存会话范围数据等)基本上已经由应用服务器本身完成。你根本不需要担心它。您可以通过HttpSession#setAttribute()#getAttribute() 在会话中设置/获取Java 对象。只有在客户端不支持 cookie 的情况下,您真正​​需要注意的是 URL 重写。然后它将在 URL 上附加一个 jsessionid 标识符。在 JSP 中,您可以为此使用 JSTL 的 c:url。在 Servlet 中,您可以为此使用 HttpServletResponse#encodeURL()。这样服务器就可以通过读取新的请求 URL 来识别客户端。

您的新问题可能是“但是 cookie 与此有什么关系?服务器是如何完成这一切的?”。好吧,答案是这样的:如果服务器收到来自客户端的请求并且服务器端代码(您的代码)试图通过HttpServletRequest#getSession() 获取HttpSession,而还没有创建任何人(新会话中的第一个请求),服务器将自己创建一个新的。服务器将生成一个长的、唯一的且难以猜测的 ID(您可以通过 HttpSession#getId() 获得的 ID)并将此 ID 设置为名称为 jsessionid 的 cookie 的值。在后台,服务器为此使用HttpServletResponse#addCookie()。最后,服务器会将所有会话存储在某种Map 中,会话 ID 为键,HttpSession 为值。

根据HTTP cookie spec,客户端需要在后续请求的标头中发回相同的cookie。在后台,服务器将通过HttpServletRequest#getCookies() 搜索jsessionid cookie 并确定其值。这样,服务器就能够获取关联的HttpSession,并在每次调用HttpServletRequest#getSession() 时将其返回。

直截了当:唯一存储在客户端的是会话 ID(类似于 cookie)和 HttpSession 对象(包括它的所有属性)存储在服务器端(在 Java 中记忆)。您自己无需担心会话管理,也无需担心安全性。

另见:

【讨论】:

  • 更新:当前的 HTTP 状态管理机制 规范是 RFC 6265,它废弃了之前的规范 RFC 2965。您可以更新答案中指向 RFC 2965 的链接(在“HTTP cookie 规范”中)。
  • @BalusC 根据上面的答案,如果我使用 url 重写,那么存储值和获取 session.setAttribute() 和 session.getAttribute() 等值的方法是什么。
  • @BalusC 请参阅我正在使用 mozilla,并且我已手动阻止接受 cookie(未选中允许 cookie)。然后我尝试存储到使用 session.setAttribute("x",x);现在在另一个页面中我正在使用 session.getAttribute(x);并且在页面上显示为空。看了你的回答后,我尝试了这种方式,然后我发表了评论。这不是使用会话属性的方式吗?
  • @javaprogrammer: 显然你没有做正确的 URL 重写。
【解决方案2】:

所有 Java Web 框架都支持 cookie 或 URL 编码的会话 ID。他们会自动选择正确的方法,因此您无需做任何事情。只需从您的容器中请求会话对象,它就会处理详细信息。

[编辑] 有两个选项:Cookie 和特殊 URL。两种方法都存在问题。例如,如果您在 URL 中编码会话,人们可以尝试传递会话(例如,通过将 URL 放入邮件中)。如果您想了解这一点,请阅读几篇有关安全性和构建应用服务器的文章。否则:您的 Java 应用程序服务器将为您做正确的事情。别想了。

【讨论】:

  • 没有其他选择,所以这个问题没有意义。
  • @Aaron,你的意思是说 cookie 是唯一可用的选项吗?
【解决方案3】:

cookie 只是存储会话 ID,会话过期后这个 ID 就没有用了。

【讨论】:

    【解决方案4】:

    Servlet specification 定义了用于在标准 J2EE 应用程序中访问/设置会话数据的 API。它还定义了会话数据存储在服务器端,除了会话标识符之外没有任何内容传输到客户端。会话 id 的传输有两种机制:

    1) 请求 URL 例如jessionid=....
    2) 饼干

    机制是根据客户端功能自动确定的。

    编辑。没有最好的选择,有定义方式的 ​​servlet 规范。

    【讨论】:

    • 您的 servlet 规范链接似乎已损坏,如果可能,您应该更新您的问题。
    【解决方案5】:

    Http 是一种无状态的、仅客户端拉取的协议。

    为了实现有状态的对话,Java EE Web Server 需要在客户端隐藏一些信息(即 sessionid),它可以使用的机制应该遵循 HTTP 和 HTML 规范。

    有三种方法可以实现这一目标:

    1. URL 重写:服务器会在 URL 链接的末尾添加一个额外的参数。
    2. 表单中的隐藏参数:服务器将在 HTML 中的每个表单中添加一个附加参数。
    3. cookie:服务器会要求浏览器维护一个cookie。

    基本上,现代网络服务器将有一个“过滤器”来选择自动使用的方式。
    所以如果Server检测到浏览器已经关闭了cookie支持,就会切换到其他方式。

    【讨论】:

      【解决方案6】:

      2 个重要问题:

      1. 您使用的是哪种网络技术? JSF、Struts、SpringMVC 或只是普通的 servlet/JSP。

        • Servlet/JSP 已经为您提供了所需的会话支持。
          JSP 示例:Hello, <%= session.getAttribute( "theName" ) %>

        • 我真的认为您不必担心 cookie,因为数据安全地存储在服务器中,并且处理 cookie 是自动完成的。

      2. 您的应用程序是否安装在单个服务器上?

        • 如果 YES 比您没有问题,请使用 servlet 会话选项。

        • 如果否,那么您必须找到另一种方法来执行此操作。就像使用粘性会话一样,或者可能将请求/响应中的整个会话对象解析为一个字段。此选项确实需要您采取安全措施。

      【讨论】:

      • JSF、Struts、SpringMVC 都建立在 servlet 规范之上。
      • 您可以从任何可以访问请求对象的地方调用 request.getSession().getAttribute(),而不仅仅是 JSP。
      • 这个问题与servlets/JSP有关。
      猜你喜欢
      • 2016-10-23
      • 2017-06-04
      • 1970-01-01
      • 2011-04-03
      • 2014-01-24
      • 2011-12-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多