【发布时间】:2017-05-27 05:53:58
【问题描述】:
我必须修复这个允许查看数据(比如客户数据)并使用 Tomcat 和 Spring 框架对其进行编辑的基本 Web 应用程序。当我尝试同时从不同的浏览器选项卡编辑不同的客户数据时,就会出现我的问题;编辑后的数据混合在一起。如果我在一个选项卡中打开要编辑的客户 A,我在另一个选项卡中打开客户 B,然后返回编辑客户 A 并保存它,客户 A 的最后更改将应用于客户 B。
稍微调查一下这个问题是因为客户数据存储在会话中,但这个会话是在不同的选项卡之间共享的。因此,当我在一个选项卡中打开客户 A 时,该客户存储在会话中,但是当我在另一个选项卡中打开客户 B 时,最新的是存储的那个。因此,当我完成对客户 A 的编辑并提交表单时,更改将应用于会话中找到的客户客户 B。
我在这里看到了针对我的问题的不同解决方案。一种解决方案是阻止用户在多个选项卡中打开我们的应用程序,但它太复杂了,我觉得它很脏。另一种解决方案是简单地为不同的选项卡使用不同的会话,但我不确定如何实现这一点。阅读此论坛时,我发现另一篇文章提到在 Tomcat 'cookies=false' 的 context.xml 文件中使用设置,但随后整个应用程序失败,我不想在非我的代码中触及不必要的内容。我还看到有人提到使用 HTML5 SessionStorage,但我找不到任何实现这个的好例子。
我认为这一定是一个常见问题,选项卡之间的共享会话,并且它必须有一个共同的解决方案。在这种情况下,什么解决方案适合?
编辑:
假设我有这个代码:
@RequestMapping(value = "edit.do", method = RequestMethod.GET)
public String edit(@RequestParam(value = "id", required = false) Long customerId, Map modelMap) {
Customer customer = getCustomer(customerId);
modelMap.put("customer", customer);
return "customer";
}
@RequestMapping(value = "save.do", method = RequestMethod.POST)
public void save(@ModelAttribute("customer") Customer customer, OutputStream outputStream,
HttpServletResponse response) throws IOException {
save(customer);
}
我不确定modelMap.put("customer", customer); 是做什么的,但我认为是客户在会话中的存储位置。我可以成功地在jsp页面中添加一个隐藏字段,并通过添加@RequestParam(value = "customerId", required = true) Long customerId,在保存方法中从数据库中检索客户现在我的问题是,我在保存方法中使用@ModelAttribute("customer") Customer customer获得的客户是从提交的客户jsp 还是存储在会话中的那个?此外,如果这是存储在会话中的,我如何检索在 jsp 中所做的更改?
【问题讨论】:
-
没有一个解决方案是正确的。正确的解决方案是首先避免将客户存储在会话中。只需使用隐藏的输入字段传递您正在编辑的客户的 ID。然后通过此 ID 从您的数据库中获取客户,并更新它。如果您真的希望您的客户在会话中,那么不要对所有客户使用相同的密钥。使用客户的 ID 作为键的一部分(例如“customer.
”),并再次使用隐藏的输入字段传递此 ID。 -
我也是这么想的,并且已经成功地测试了这个,但是我不想更改不是我的代码。让所有单元测试再次运行良好看起来像是一场噩梦。我认为最好问问标准的做法是什么。
-
@danielsp 没有标准的方法来修复糟糕的设计。正确的方法是投入时间、金钱和精力来修复它。通常,您最终会在胶带顶部的黑客顶部找到补丁,因为您必须反复进行快速而肮脏的修复。
-
我试图去隐藏字段。这里的问题是,在 save 方法中传递的 Customer 对象始终是为最近打开的选项卡生成的 Custom 对象,因此它只包含此选项卡中的更改。问题是在 jsp 文件中有一个
标签: java spring jsp tomcat servlets