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

2022-09-01 23:48:16

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

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

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

添加一些检测到从另一个选项卡请求另一个流的验证,并向用户显示一条消息,说这是不允许的,这也不是一个选项,因为它惹恼了用户,我们不希望这样吗?:D

事实是,使用另一个选项卡对用户很有用,因为他们在使用应用程序方面更有效率,所以我保留了此选项。但现在的问题是,如何最好地管理更多选项卡的一个会话数据?

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

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

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

你遇到过这种情况吗?你是如何处理的?


答案 1

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

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

  • 将 a 传递给每个请求,并将其返回给下一个请求。第一次 - 生成它。windowId
  • 对于要存储在会话中的任何属性,请将 a 放在键为Map<String, Object>windowId

答案 2

这正是Seam被创造出来要处理的事情。在Seam中,有一个叫做Conversation的概念,它基本上完全符合你的解释。对话基本上是将会话划分为多个部分的一种方式,这些部分可能会在某个超时时时过期。您可以查看 org.jboss.seam.core.Manager 类的源代码,了解它的实际实现方式,并;)


推荐