弹簧MVC在控制器之间传递相同的物体

2022-09-04 07:11:49

在Spring MVC中,如何在两个控制器方法之间传递对象?我有一个更新表单和一个更新控制器。在控制器中,我有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。如何确保通过视图传递相同的对象。我不想将对象添加为会话属性,因为用户可能会修改会话中的许多员工。


答案 1

您有 3 个选项

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

备选案文1

  1. 将注释添加到控制器类@SessionAttributes
  2. 将 as 作为参数添加到更新方法中,并在完成对象处理完该方法后将其添加到该方法中SessionStatussetComplete()

@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. 清理方法,因为它应仅返回视图名称showEmpDetails

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

我不会选择选项,我强烈建议选项1,特别是包括要清理的对象。您也可以将 1 和 2 组合在一起(具有带注释的方法,并且仍使用 .)。setComplete()SessionStatus@ModelAttribute@SessionAttributes


答案 2

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

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


推荐