如何为单个浏览器选项卡/窗口存储状态?

时间:2012-11-08 15:44:16

标签: java servlets

我正在开发单页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 Session对象中,我不必考虑生成会话ID。但现在我必须把它存放在其他地方,在哪里?

有没有人有这种设置的经验并且可以帮助我?

更新
感谢BalusC这个非常有趣的方法。
当我理解你的时候,这意味着:

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

2 个答案:

答案 0 :(得分:3)

在初始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插件来激活表单,这应该不是一个大问题。)

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

答案 1 :(得分:0)

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

Session shared in between tabs