问题: 每当我们将两个不同记录的数据保存在同一会话的浏览器的两个不同选项卡中时,数据就会混合在一起,用于各自保存的记录。
情境: 1) Tab1:打开浏览器并登录应用程序并进入搜索屏幕。 (在我们的案例中,保证人搜索屏幕)。
2) Tab2 :在同一浏览器中打开另一个浏览器标签,复制上一步的网址并将其粘贴到当前标签中,现在两个标签中都会打开搜索屏幕。
3)返回到Tab1并搜索一个担保人(例如:保证人,其中包含34526等号码),并在搜索屏幕上显示结果后打开一次。
4)然后转到Tab2并搜索另一个保证人记录并打开它。
5)现在点击编辑按钮编辑在Tab2中打开的记录,然后返回到Tab1而不编辑Tab2中的数据。
6)现在点击编辑按钮编辑在Tab1中打开的记录,然后进行修改并在此屏幕中执行一些操作,例如' SAVE'操作,同时转到Tab2并点击' SAVE'在这个屏幕上也可以操作。现在,我们点击了Tab1上的保存按钮,在Tab1完成保存操作之前的平均时间,我们在Tab2中也做了另一个动作(即SAVE)。
7)现在,两个屏幕的数据混合在一起(这不是正确的行为)。在这种情况下,数据不应该混淆,应该为相应的记录正确保存。 请注意,在上面的场景中,打开的屏幕对于两个选项卡都是相同的,但具有不同的记录。 (例如:打开“编辑担保人”的屏幕,但有两个不同的担保人记录。)
客户首选解决方案:
应用程序应允许对多个选项卡中打开的记录进行更改,而不会中断应用程序流。登录到应用程序的用户在这种情况下是相同的,应用程序应该允许多标签功能,而不会混淆数据。
问题的可能根本原因是:
1)IE 7及更高版本的浏览器版本在整个浏览器中维护单个会话,即使您打开新窗口,它也将具有相同的会话。 由于我们使用的是IE8,它甚至可以通过不同的Tabs维护单个会话。这可能会造成这个问题。
我们对上述问题进行了一些研究,并检查了一些博客,但我们无法为我们的问题找到正确的解决方案。
我们检查了几个问题来解决这个问题:
1) SessionStorage 概念可以从HTML5获得,并且可以从IE8 +浏览器支持,但是这个解决方案不支持我们上面提到的要求。如果有人在此帮助下得到上述结果,请告诉我们。
2)我们找到了另一个解决方案:URL重写 - (附加会话详细信息和一些独特的细节以区分会话并维护一些隐藏的字段以跟踪每个页面中的会话) - 但这非常复杂,我们也不确定这是否解决了上述问题。如果有任何相关建议,请告诉我们。
我们还尝试了一些JavaScript编码示例,但没有得到所需的解决方案。
如果某人已经在他们的申请中实施了,我们期待一些指导或类似的解决方案。
答案 0 :(得分:0)
您是否尝试将表单bean的范围设置为请求?默认情况下,struts的表单bean是会话作用域。因此,您发布回服务器的bean将在选项卡之间共享。如果将范围设置为request,那么您将在不同的选项卡中使用不同的表单bean。这将确保当用户点击保存时,数据不会混淆。
答案 1 :(得分:0)
我已经看到这个问题有几个struts应用程序要求用户在多个页面上填充数据(用户在一个页面上填充数据,点击下一个...到达最后一页并单击保存然后保存数据在数据库中)。当用户点击下一页转到下一页时,当前页面(表单)数据将保存在HttpSession中(如果bean范围是会话,Struts会自动执行此操作)。当用户在多个选项卡或浏览器窗口中打开应用程序时(假设用户对多个窗口使用相同的浏览器(例如IE))并对不同记录的表单执行操作,数据将在同一会话中保存/覆盖并被破坏。你的情况也很相似。
正如你正确地指出jsessionID实现起来有点复杂,因为如果你在网页上渲染一些链接(从xml文件指向应用程序的其他部分的链接),你需要将jsessionID嵌入到URL否则服务器将分配一个新的jsessionID并将用户重定向到登录页面(假设您的企业应用程序要求用户先登录)(动态生成的链接将嵌入jsessionID)。这种方法的第二个问题是:如果用户右键单击任何链接(假设嵌入了jsessionID)并选择在新窗口/选项卡中打开,然后导航到其他记录进行编辑,则数据将被破坏(请注意当用户在新选项卡中为链接选择打开时,该链接的URL将具有来自父窗口/选项卡的相同jsessionID。
要解决此问题,您必须在应用程序中进行一些设计更改。以下是可行的方法。
不是将数据存储在HttpSession中,而是可以将数据存储在缓存中(您可以使用自己的逻辑将数据存储为键值对,如下所述)。我想你必须遵循以下步骤: a)将bean范围更改为来自会话的请求。 b)为每个窗口/选项卡指定唯一标识符。您可以使用相同的windows.name属性。所有主流浏览器都支持此属性。每次单击next / previous / save时,都应将此选项卡/窗口名称发送到服务器。 c)在服务器端存储数据,可以遵循以下方法(可能不是最好的,随意调整它。:-))
HashMap -> key will be the jessionID and value will be another HashMap.
- HashMap(value of the first Map) -> key will be tab/windows name sent from the browser. Value will be another HashMap.
- HashMap (value of the second map) -> Key will be form name. Value will be the actual form. (this map will have only one entry, if you have only one form).
d) Once you approach on the last page, get all the forms from the Map for the desired tab/window and save in the database.
对于上面提到的(c)点,您可以使用数据库来存储中间数据。这两种方法都有利有弊。 i)与数据库相比,在地图/数据结构中存储/检索数据的速度更快。 ii)在数据结构中存储数据会占用堆上的空间。但是到目前为止,您将数据存储在会话中,因此不应该成为问题。 iii)如果存储在DS中,则在服务器崩溃的情况下数据丢失。从数据库中可以检索数据。