管理多个选项卡的 Web 应用程序会话数据/控制器流
我有一个 Java Web 应用程序,它在会话中存储一些数据。当用户与应用程序交互时,会话中的数据会发生变化(例如,流程由控制器管理,每个控制器有多个表单页面,在每个表单页面上,会话中的一些数据会更新,并且流程会转到下一个表单页面)。
问题在于,某些用户向应用程序打开多个选项卡,每个选项卡在流程中都有不同的步骤。此时,会话中的数据会变得混乱,因为选项卡共享相同的会话(应用程序使用 cookie 管理的会话)。
告诉用户使用不同的浏览器以避免共享相同的会话 ID(例如一个 Firefox 窗口和一个 IE 窗口)不是一种选择,因为肯定在某些时候有人会忘记这样做,而是使用选项卡,从而弄乱他们的数据。
添加一些验证来检测从另一个选项卡请求另一个流并向用户显示一条消息说这是不允许的,这也不是一个选项,因为它会激怒用户,我们不希望这样,不是吗? :D
事实上,使用另一个选项卡对用户来说很有用,因为他们使用应用程序的效率更高,所以我保留这个选项。但现在的问题是如何最好地管理多个选项卡的一个会话数据?
我的想法是让控制器在启动流程时生成一个令牌并将该令牌传递给每个表单页面,该页面又将其发送回以标识其自身。如果在存在正在进行的流程时另一个选项卡请求相同的控制器操作,则生成另一个令牌并将其传递。
基本上,我希望每个流都有一个令牌,并且在会话中我不仅保留一组数据,而且为每个令牌保留一组数据,然后根据令牌匹配请求。
现在的问题是,这种方法需要对应用程序进行大量重写,我想知道是否有管理这种情况的最佳实践,或者有人可以建议其他方法。我对想法持开放态度。
你遇到过这种情况吗?你是怎么处理的?
I have a Java web application which stores some data in the session. The data in the session changes as the user interacts with the application (e.g. flow is managed by a controller, each controller has several form pages, on each form page some data is updated in the session and flow goes to the next form page).
The problem is that some users are opening more than one tab to the application, each tab with a different step in the flow. At this point data in the session is messed up since the tabs share the same session (app uses cookie managed sessions).
Telling the users to use different browsers to avoid sharing the same session id (e.g. one Firefox window and one IE window) is not an option since surely at some point somebody will forget to do this and instead use tabs, thus messing up their data.
Adding some verifications that detect that another flow is requested from another tab and display a message to the user saying this is not allowed is not an option either since it pisses of the users and we don't want that do we? :D
The fact is that using another tab is useful for the users because they are more efficient in what they use the application for, so I am keeping this option. But the question now is how best to manage the one session data for the more tabs?
What I thought of, was to have the controller generate a token when it starts the flow and pass this token to each form page which in turn sends it back to identify itself. If another tab requests the same controller action when there is an ongoing flow then generate another token and pass that around.
Basically, I want each flow to have a token and inside the session I won't just keep one set of data but have a set of data for each token and then match requests based on the token.
Now the problem is that this approach will need a lot of rewritings to the application and I was wondering if there is a best practice for managing such a situation or can someone suggest other approaches. I am open to ideas.
Have you encountered this situation? How did you handle it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这通常是通过为每个选项卡/窗口分配一个 windowId 并在每个请求上传递它来完成的。 Jsf 通过 orchestra 支持此功能。 Spring mvc 将在下一个版本中支持它。
最近因为一个简单的案例需要这个,所以我自己实现了。花了半个小时。然而,我的范围非常有限:
windowId
,并为下一个请求返回它。第一次 - 生成它。Map
,其中键是windowId
This is usually done by assigning a windowId for each tab/window and passing it on each request. Jsf supports this via orchestra. Spring mvc will support it in the next version.
I recently needed this for a simple case, so I implemented it myself. Took half an hour. However, my scope was very limited:
windowId
with each request, and return it back for the next request. The first time - generate it.Map<String, Object>
where the key is thewindowId
这正是 Seam 的创建目的。在 Seam 中,有一个称为 对话< /a> 基本上完全符合您所解释的内容。会话基本上是一种将会话分成许多部分的方法,这些部分可能会在某个超时后过期。您可以查看 org.jboss.seam.core.Manager 类的源代码,了解它的实际实现方式并获得灵感;)
This is exactly what Seam was created to handle. In Seam there's a concept called a Conversation which basically does exactly what you are explaining. Conversations are basically are a way to divide the Session into many pieces that can expire at some timeout. You can look at the source code for org.jboss.seam.core.Manager class to see how it's actually implemented and get inspired ;)
根据应用程序的复杂性,您可能需要研究在应用程序中实现选项卡。这使您可以全面控制流程,同时仍然为用户提供他们想要的功能。我认为,就错误而言,这是最强大的解决方案,因为您不会依赖浏览器处理会话的方式,从而最大限度地减少“已知未知数”的数量。
当然,这可能会产生大量的前期成本,具体取决于您的应用程序的结构。如果没有有关您的应用程序的更多信息,您就是最适合做出决定的人。
Depending on the complexity of your application, you may want to investigate implementing tabs within your application. This gives you wholesale control over the flow, while still providing users with the functionality they want. I'd argue it's, bugwise, the most robust solution, since you won't have a dependency on the way the browser handles sessions, minimising the number of "known unknowns".
Of course, there'll be potentially a large upfront cost to this, depending on how your application is structured. Without more information about your app, you're the best placed person to decide.
您还可以尝试将您的应用程序包装在 Adobe Air 内
,然后限制您的 Web 应用程序仅可以从这个空中访问。通过这样做,您无需考虑网络浏览器碎片及其独特的行为。
You can also try to wrap your application inside Adobe Air
And then limit your web application to be only accessable from this air. By doing this you dont need to consider the web browser fragmentation and their unique behaviour.