管理多个选项卡的webapp会话数据/控制器流

我有一个Java Web应用程序,它在会话中存储一些数据。 当用户与应用程序交互时,会话中的数据发生变化(例如,流程由控制器管理,每个控制器具有多个表单页面,在每个表单页面上,一些数据在会话中更新,流程转到下一个表单页面)。

问题是一些用户正在向应用程序打开多个选项卡,每个选项卡在流程中都有不同的步骤。 此时会话中的数据混乱,因为选项卡共享同一会话(应用程序使用cookie托管会话)。

告诉用户使用不同的浏览器以避免共享相同的会话ID(例如,一个Firefox窗口和一个IE窗口)不是一种选择,因为在某些时候肯定会有人忘记这样做而是使用制表符,从而弄乱他们的数据。

添加一些检测从另一个选项卡请求另一个流并向用户显示不允许这样的消息的validation不是一个选项,因为它对用户很生气而我们不希望这样做吗? :d

事实是,使用另一个选项卡对用户非常有用,因为它们在使用应用程序时更有效,所以我保留了这个选项。 但现在的问题是如何最好地管理更多标签的一个会话数据?

我想到的是让控制器在启动流时生成一个令牌,并将此令牌传递给每个表单页面,然后将其发送回标识自身。 如果另一个选项卡在有正在​​进行的流时请求相同的控制器操作,则生成另一个令牌并传递它。

基本上,我希望每个流都有一个令牌,在会话中我不仅会保留一组数据,而是为每个令牌提供一组数据,然后根据令牌匹配请求。

现在的问题是这种方法需要对应用程序进行大量的重写,我想知道是否有管理这种情况的最佳实践,或者有人可以建议其他方法。 我对这些想法持开放态度。

你遇到过这种情况吗? 你是怎么处理的呢?

这通常通过为每个选项卡/窗口分配windowId并在每个请求上传递它来完成。 Jsf通过管弦乐队支持这个。 Spring mvc将在下一个版本中支持它。

我最近需要一个简单的案例,所以我自己实现了它。 花了半个小时。 但是,我的范围非常有限:

  • 传递一个带有每个请求的windowId ,并将其返回以进行下一个请求。 第一次 – 生成它。
  • 对于要存储在会话中的任何属性,请放置一个Map ,其中键是windowId

这正是Seam创建的处理方式。 在Seam中有一个名为Conversation的概念,它基本上完全符合您的解释。 对话基本上是一种将会话划分为多个片段的方法,这些片段可以在某个超时时间到期。 您可以查看org.jboss.seam.core.Manager类的源代码,看看它是如何实际实现的并得到启发;)

根据应用程序的复杂程度,您可能需要调查应用程序中的实现选项卡。 这使您可以批量控制流,同时仍然为用户提供他们想要的function。 我认为这是最强大的解决方案,因为你不会依赖浏览器处理会话的方式,最大限度地减少“已知未知数”的数量。

当然,根据应用程序的结构,这可能会有很大的前期成本。 如果没有关于您的应用的更多信息,您就是最适合自己决定的人。

您还可以尝试将应用程序包装在Adobe Air中

然后限制您的Web应用程序只能从这个空中访问。 通过这样做,您不需要考虑Web浏览器碎片及其独特的行为。