我有一个Spring Web应用程序(Spring 3.2),我使用了以下场景来处理编辑页面:
@Controller
@SessionAttributes(value = { "packet" })
public class PacketController {
@RequestMapping(value = "/edit-packet/{packet_id}", method = RequestMethod.GET)
public String editPacketForm(@PathVariable(value = "packet_id") Long packet_id, Model model)
{
model.addAttribute("packet", packetService.findById(packet_id));
return "packets/packetEdit";
}
POST方法:
@RequestMapping(value = "/edit-packet/{packet_id}", method = RequestMethod.POST)
public String packetEditAction(Model model, @Valid @ModelAttribute(value = "packet")
Packet packet, BindingResult result, SessionStatus status)
{
if (result.hasErrors())
{
return "packets/packetEdit";
}
packetService.update(packet);
status.setComplete();
return "redirect:/";
}
现在问题是,如果有人试图使用不同的ID为/ edit-packet / {id}打开多个标签。每个新的打开标签都会显示会话数据包'对象将被覆盖。然后在尝试在多个选项卡上提交表单后,将提交第一个选项卡,但它实际上会更改第二个数据包,因为在会话中是第二个对象,第二个选项卡将导致错误,因为已调用setComplete,因此没有'数据包&#39 ;会话中的对象。
(这是已知问题https://jira.spring.io/browse/SPR-4160)。
我正在尝试实施此解决方案http://duckranger.com/2012/11/add-conversation-support-to-spring-mvc/来解决此问题。我复制了ConversationalSessionAttributeStore.java ConversationIdRequestProcessor.java类和我的servlet-config.xml中我做了这个:
<mvc:annotation-driven />
<bean id="conversationalSessionAttributeStore"
class="com.xx.session.ConversationalSessionAttributeStore">
</bean>
<bean name="requestDataValueProcessor" class="com.xx.session.ConversationIdRequestProcessor" />
但它不起作用,在我的POST方法中我没有看到任何新参数,我是否错过了什么?
更新:实际上,它已经开始运作,但也许有人有更好的想法来解决这个问题?
我的另一个想法是在每个新标签上强制使用新会话,但这不是一个好的解决方案。
答案 0 :(得分:1)
不要使用会话属性,使控制器无状态,只需使用路径变量来检索正确的模型属性。
@Controller
public class PacketController {
@ModelAttribute
public Packet packet(@PathVariable(value = "packet_id") Long packet_id) {
return packetService.findById(packet_id);
}
@RequestMapping(value = "/edit-packet/{packet_id}", method = RequestMethod.GET)
public String editPacketForm() {
return "packets/packetEdit";
}
@RequestMapping(value = "/edit-packet/{packet_id}", method = RequestMethod.POST)
public String packetEditAction(Model model, @Valid @ModelAttribute(value = "packet")
Packet packet, BindingResult result) {
if (result.hasErrors()) {
return "packets/packetEdit";
}
packetService.update(packet);
return "redirect:/";
}
}
这样的事情应该可以解决问题。