Spring MVC - 在ajax请求之间保持对象状态

时间:2015-01-23 18:42:28

标签: ajax spring-mvc

Spring MVC 4.1

您好, 我有一种情况,在一个页面上,有几个输入字段。当用户在这些字段中输入数字时,将发生一系列计算并更新页面上的各种其他字段。 我希望整个计算模型在服务器端的Java中进行。我真的想避免在客户端的Javascript中复制这个逻辑。

我想象的是......

  • 用户打开页面,创建计算的对象(我们称之为计算器),并设置其初始状态(其中许多字段预先填充了值)。
  • 此计算器实例在用户在该页面上的时间内存储并可用。
  • 每当用户更改输入字段中的值时,该新值将通过ajax发送到服务器并插入到我们的Calculator对象中。计算器,根据新状态重新计算其他字段,并将结果返回到页面。
  • 页面上的其他字段会相应更新。

这里的关键是我没有用每个ajax请求发送所有字段的状态。我只发送更新的当前值。本质上,我正在尝试确保后端的表单状态和计算器状态始终是同步的。

我已经研究过@SessionAttributes和@ModelAttribute。

@ModelAttribute的问题,据我所知,是每次ajax请求都会重新创建它。

@SessionAttributes的问题在于它是一个会话变量。如果用户打开了其中两个窗口怎么办?如何确保对象在离开页面时从会话中删除?等...

也许没有神奇的Spring子弹,我只需要找出会话变量的东西。但是,任何关于处理这个的指针都会非常感激。

谢谢!

2 个答案:

答案 0 :(得分:0)

您有几个选择:

0.1。就像你说过使用@SessionAttributes一样,不过它是你所提到的问题,同一个会话的多个实例会看到同一个变量。

0.2。将状态存储在其他位置并使用@ModelAttribute带注释的方法重新保持状态。我个人更喜欢这种方法,主要是在创建表单时,使用当前状态的标识符创建它:

@RequestMapping(params = "form")
public String createForm(Model uiModel) {
    uiModel.addAttribute("calculationId", UUID.randomUUID().toString());
    return "calculationpage/create";
}

然后,对于后续的ajax请求,请确保您之前的calculateId发送到:

@ModelAttribute("calculationState")
public CalculationState rehydrateState(String calculationId) {
    //retrieve current state of calculation from some persistent store..
}

@RequestMapping("/calculate")
public String handleCalculation(@ModelAttribute("calculationState") CalculationState c) {
    //you will get a calculationstate with the delta's at this point..
}

0.3。另一种可能的方法可能是使用会话,但使用自定义ID消除会话中不同实例的消歧:

   public String handleCalculation(HttpSession session, @RequestParam("calcId") String calcId) {
     CalculationState calcState = (CalculationState) session.getAttribute("calculation" + calcId);
   }

答案 1 :(得分:0)

您需要在会话外部使用任何类型的持久存储来存储和检索计算器模型的状态。像Biju说的那样,我会选择像No 2这样的解决方案。