【问题标题】:How can I store state for an individual browser tab/window?如何存储单个浏览器选项卡/窗口的状态?
【发布时间】:2012-10-28 20:20:22
【问题描述】:

我正在开发一个单页 jQuery 和 Backbone.js 网络应用程序。后端是 JBoss 6 应用服务器。

到目前为止,我们有以下结构:

  • 只有一个 servlet(前端控制器)。来自 JavaScript 客户端的每个请求都经过这里。
  • 在 servlet 中 - 在某个 JS 客户端的第一个请求中 - 我查看了一个有状态会话 bean。对于该客户端的下一个请求,我将查找结果存储在 HTTP 会话容器中。所以每个 JS 客户端都只有一个有状态的会话 bean。此连接由会话 cookie 保存。

现在我有一个额外的要求:

当用户有两个浏览器选项卡(在一个浏览器中)时,他们应该在每个浏览器选项卡中都有两个独立的 Web 应用实例。因此,我对会话 cookie 有疑问,因为此会话 cookie 适用于所有浏览器选项卡。

我必须改变结构,以便:

  • servlet 必须为某个 JS 客户端的第一个请求生成一个新的会话 ID。此会话 ID 被传达给客户端。
  • 对于后端的每个 POST,JS 客户端都必须发送此会话 ID。

我的问题是:

到目前为止,我将查找结果保存在一个 HTTP 会话对象中,而我还没有考虑生成会话 ID。但是现在我必须将它存储在其他地方,在哪里?

有没有人经历过这种设置并可以帮助我?

更新:
感谢 BalusC 提供这种非常有趣的方法。
当我很好理解你时,这意味着:

一个浏览器的标签页的所有单独的JS客户端共享一个HTTP会话对象。在这个 HTTP 会话对象中,每个选项卡都有自己的入口点。这听起来真的很好。所以我仍然可以使用整个 HTTP 会话基础架构,而不必重新发明轮子。

【问题讨论】:

    标签: java servlets


    【解决方案1】:

    在您存储的初始 GET 请求上自动生成一个唯一值,并在每个后续回发中作为隐藏输入值传递。将此唯一值用作表示视图范围数据的会话属性的标识符。

    在全新会话的第一个请求期间,请执行以下操作:

    Map<String, ViewData> viewScope = new HashMap<String, ViewData>();
    session.setAttribute("viewScope", viewScope);
    

    ViewData 表示您希望跨同一视图的回发跟踪的视图特定数据)

    在每个 GET 请求期间,执行以下操作:

    String viewDataId = UUID.randomUUID().toString();
    viewScope.put(viewDataId, new ViewData());
    request.setAttribute("viewDataId", viewDataId);
    

    在生成 HTML 时,执行:

    <input type="hidden" name="viewDataId" value="${viewDataId}" />
    

    在每个 POST 请求期间,执行以下操作:

    ViewData viewData = viewScope.get(request.getParameter("viewDataId"));
    // Get/set view-specific data in there.
    

    确保 jQuery 也传递这个隐藏的输入(如果您已经正确使用 $(form).serialize() 或例如 AjaxForm 插件来 ajaxify 表单,这应该不是什么大问题)。

    如果您熟悉 Java EE 的 MVC 框架 JSF,那么了解其 @ViewScoped 注释的工作方式与上述大致相同可能会很有用。另见 a.o. How to choose the right bean scope?

    【讨论】:

      【解决方案2】:

      您可以将会话跟踪与 URL 重写结合使用。见这里:

      Session shared in between tabs

      【讨论】:

      • 我相信您不了解会话跟踪在客户端的实际工作原理。以这种方式无法为每个浏览器窗口/选项卡创建单独的会话。
      • 为什么不呢?每个选项卡都可以有它自己的会话 ID 作为 URL 中的 GET 参数,如下所示:http:\\www.myapp.com?session-id=02393vdr8t。 ID 由 WebServer 处理,但您必须对每个 URL 进行编码。它类似于您的解决方案,但不是隐藏的输入值。见这里:[链接]stackoverflow.com/questions/6243201/….
      猜你喜欢
      • 2012-03-14
      • 1970-01-01
      • 1970-01-01
      • 2020-06-01
      • 2015-10-19
      • 1970-01-01
      • 2017-06-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多