Spring MVC在控制器之间传递相同的对象

时间:2014-01-29 09:09:09

标签: java spring spring-mvc

在Spring MVC中,如何在两个控制器方法之间传递对象?我有一个更新表单和一个updateController。在控制器中我有2个方法,一个用于获取数据并在视图中显示它。当用户单击带有修改的更改的更新按钮时,将调用控制器的第二种方法。我观察到的是我在控制器的第二个方法中得到的对象与我在第一个控制器方法调用中传递给视图的对象不同。它是一个新对象,所有表单字段都映射到它。如何确保将相同的对象传递给第一个控制器方法提供给视图的第二个控制器方法?

@RequestMapping(value = "/showEmpDetail.html", method = RequestMethod.GET)
public String showEmpDetails(
        @RequestParam(value = "page", required = false) Integer page,
        HttpServletRequest request, @RequestParam("empId") Long empId,
        ModelMap model) {
    // Get employee using empId from DB
    model.addAttribute("emp",emp);
    return "showEmpDetail";
    }

上述控制器方法从Db获取emp值并在视图中正确显示。现在用户更改了一些细节并单击了提交按钮。调用以下控制器方法。

@RequestMapping(value = "/editEmpFormSubmission.html", method = RequestMethod.POST)
public String editEmpFormSubmission(
        @RequestParam(value = "page", required = false) Integer page,
        @ModelAttribute("emp") Employee emp, BindingResult result,
        ModelMap model, HttpServletRequest request) {
     // update changes in DB
    }

在上面的控制器方法中,当我检查emp对象时,它与我在之前的控制器调用中传递的对象不同。未形成后备但具有值的字段已更改为null。如何确保视图传递相同的对象。我不想将对象添加为sessionAttribute,因为用户可能会修改会话中的许多员工。

2 个答案:

答案 0 :(得分:25)

您有3个选项

  1. 使用@SessionAttributes将请求中的对象存储在会话中。
  2. 使用@ModelAttribute带注释的方法在每个请求之前检索对象
  3. 编写您自己的代码并将其存储在会话中(类似于1,但您需要做更多的工作)。
  4. 选项1

    1. @SessionAttributes注释添加到控制器类
    2. SessionStatus作为参数添加到更新方法中,并在完成对象时添加setComplete()方法

    3. @SessionAttributes("emp")
      public class EmployeeController {
      @RequestMapping(value = "/editEmpFormSubmission.html", method = RequestMethod.POST)
      public String editEmpFormSubmission(
          @RequestParam(value = "page", required = false) Integer page,
          @ModelAttribute("emp") Employee emp, BindingResult result,
          ModelMap model, HttpServletRequest request
          SessionStatus status) {
       // update changes in DB
       status.setComplete();
      }    
      } 
      

      选项2

      1. 添加从数据库中检索对象的方法,并使用@ModelAttribute
      2. 对其进行注释
      3. 清理showEmpDetails方法,因为它只应返回视图名称

      4. public class EmployeeController {
        
            @ModelAttribute("emp")
            public Employee getEmployee(@RequestParam("empdId") Long id) {
                // Get employee using empId from DB
                return  emp;
            }
        
            @RequestMapping(value = "/showEmpDetail.html", method = RequestMethod.GET)
            public String showEmpDetails() {) {
                return "showEmpDetail";
            }
        }
        

        选项3

        1. 在您的方法中添加HttpSession作为参数
        2. 在将showDetails方法添加到模型旁边的方法中,将其添加到会话
        3. editEmpFormSubmission中使用会话中的那个并将所有非空字段从会话中复制到该对象并将其存储在数据库中。
        4. 我不会选择,我强烈建议选项1,特别是在setComplete()对象上包含SessionStatus进行清理。您还可以将1和2合并(使用@ModelAttribute带注释的方法并仍使用@SessionAttributes。)。

答案 1 :(得分:0)

  

如何确保视图传递相同的对象。我不想将对象添加为sessionAttribute,因为用户可能会修改会话中的许多员工

您可以在初始渲染时在对象中创建一个填充了随机数的字段,然后将该对象存储在会话中。在视图中,您可以使用隐藏输入映射该字段,现在当用户发送编辑操作请求时,您可以获取该隐藏字段,并通过隐藏字段中的数字从会话中获取原始对象。这将解决不同标签冲突中的多个编辑。