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

Java 管理多个选项卡的webapp会话数据/控制器流,java,session,jsp,servlets,Java,Session,Jsp,Servlets,我有一个Java web应用程序,它在会话中存储一些数据。当用户与应用程序交互时,会话中的数据会发生变化(例如,流由一个控制器管理,每个控制器有几个表单页面,在每个表单页面上,一些数据会在会话中更新,流会转到下一个表单页面) 问题是一些用户正在向应用程序打开多个选项卡,每个选项卡在流程中具有不同的步骤。此时,会话中的数据被弄乱了,因为选项卡共享同一个会话(应用程序使用cookie管理的会话) 告诉用户使用不同的浏览器以避免共享相同的会话id(例如,一个Firefox窗口和一个IE窗口)不是一个选

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

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

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

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

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

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

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

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


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

这通常是通过为每个选项卡/窗口分配一个windowId并在每个请求中传递它来完成的。Jsf通过以下方式支持这一点。将在下一版本中支持它

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

  • 在每个请求中传递一个
    windowId
    ,并在下一个请求中返回它。第一次-生成它
  • 对于要存储在会话中的任何属性,请在键为
    windowId

这正是我们创建来处理的。在Seam中有一个叫做a的概念,它基本上就是你所解释的。会话基本上是一种将会话划分为多个部分的方法,这些部分可能在某个超时时过期。您可以查看org.jboss.seam.core.Manager类的源代码,了解它是如何实际实现的,并从中获得灵感;)

根据应用程序的复杂性,您可能需要研究在应用程序中实现选项卡。这使您能够全面控制流,同时仍然为用户提供他们想要的功能。我认为,从错误的角度来看,这是最健壮的解决方案,因为您不会依赖浏览器处理会话的方式,从而将“已知未知”的数量降至最低


当然,这可能会带来巨大的前期成本,具体取决于应用程序的结构。如果没有关于应用程序的更多信息,您将是最合适的人选。

您也可以尝试将应用程序包装在内部


然后将您的web应用程序限制为只能通过此air访问。通过这样做,您不必考虑Web浏览器碎片及其独特的行为。

使用单独的选项卡和单独的窗口没有区别。会话范围是浏览器范围的,因为它是使用cookie实现的(大多数情况下)。您使用的是什么技术堆栈?JSP+servlet?JSF?@mattball:我在使用servlet+jsp。我已经更新了我的问题。我知道会话跨越了整个浏览器,这就是为什么我提到这两个窗口是一个IE另一个Firefox。好的,当你真正的意思是“使用不同的浏览器”时,是“使用不同的窗口而不是选项卡以避免共享同一个会话id”。谢谢你的回答。这就是你所指的吗?对就这样。我用过它,它工作很顺利。但是它需要spring。你从哪里得到spring MVC很快就会处理对话的印象?好吧,这还没计划好。SpringWebFlow是围绕对话/流概念构建的。对话是可选的并行对话(windows),通过实现版本化的数据存储,流允许浏览器来回处理。@fforw来自Juergen Hoeller 12月的演示文稿。但是,它可能已被删除。在不更改url的情况下,如何在每个请求中传递该windowId?例如,在get请求中,我(必须)使用一个产品来尝试实现该版本。结局往往不好。用户仍然希望使用标准的浏览器导航,而且你无法阻止他们打开新的选项卡,并期待最好的结果。我相信在这方面有可能比我所经历的做得更好,但我怀疑这是微不足道的。