【问题标题】:What is the Scope of Bean declared in @ModelAttribute annotation@ModelAttribute 注解中声明的 Bean 的 Scope 是什么
【发布时间】:2014-02-19 08:41:43
【问题描述】:

我有一个包含 40 列的表和一个对应于该表的 bean。但在页面上我只显示 10 个字段。当页面被渲染时,通过调试,我可以看到 bean 被表中的所有字段填充,我正在使用 model.addAttribute("emp", emp) 将它添加到模型中。但是在更改页面上的某些字段后,当我再次提交页面时,我看到只有那些出现在页面上的字段被填充。尽管 bean 在“会话”范围内,但其余的不是。

我有一个在提交页面时调用的控制器。如下所示

@RequestMapping({"/update.html"})
public String updateData(@ModelAttribute("emp") Employee emp){
    // All fields of Employee bean are not getting populated
}

我在 JSP 中写了类似下面的内容。

<jsp:useBean class="com.Employee" id="emp"
    scope="request" />

注意:- 我也使用 scope="session" 进行了测试。

所以我的问题是,即使将 bean 放在 SESSION 范围内,为什么我没有在我的控制器中得到它。那么@ModelAttribute 是如何改变我的 bean 范围的吗??

【问题讨论】:

  • 因为我也使用了 jQuery,所以同时我将所有这些字段放在 JSP 中,将它们隐藏起来,并且我的 bean 被我控制器中的所有字段填充。方法对了吗???

标签: java spring-mvc modelattribute


【解决方案1】:

@ModelAttribute 在方法参数上本质上将模型(您通过字段提交的内容)与类型(在本例中为 Employee)绑定,并将此绑定类型公开为可以在 jsp 中使用的模型。在这一点上,它根本不是 Spring bean,只是请求范围内的对象。

现在,关于如何预填充您的 bean,一种更简洁的方法可能是在您的控制器中定义另一个用 @ModelAttribute 注释的方法,该方法负责以这种方式从数据库中加载您的模型:

@ModelAttribute("emp")
public Employee loadModelAttributes(@RequestParam("empid") int empid){
    // return employee fully populated..
}

这将确保在您的控制器方法中,只有您从 UI 提交的字段现在更新到您从数据库填充的基本 Employee,这样您就不必在隐藏变量。

@RequestMapping({"/update.html"})
public String updateData(@ModelAttribute("emp") Employee emp){
    // All fields of Employee bean are not getting populated
}

【讨论】:

  • 赞成另一种方法,但这不是我想要的。我认为,在方法之前编写 @ModelAttribute("emp") 和在方法中编写 model.addAttribute("emp") 都是相同的。其次,当页面被渲染时,我的 bean 正在正确填充(没有问题)。提交页面时出现问题。那时我没有看到我的 bean 中的所有非显示字段。我希望我的 bean 中的所有字段都被填充。
  • @Jai,这是 Spring MVC 的预期行为,当您将类型指定为 @RequestMapping 方法的参数时,您在表单中提交的字段将绑定到该类型。现在,当您使用 @ModelAttribute 注释该字段时,它将为您创建一个具有该名称的模型。此外,如果您想预先填充模型,然后使用您提交的内容进行更新,您可以按照我的建议进行操作 - 即使用另一种带有 @ModelAttribute 注释的方法,该方法可以基于 DB 填充内容。
  • 感谢@Biju,但我在预填充 bean 时没有遇到任何问题。我在这里显示的代码以 Employee 为例,这可能会让你觉得我正在家里尝试一些东西。但它不是那样的。这就是我在公司面临的问题,我无法改变应用程序的架构。你的建议很好,但对我来说并不实用。
【解决方案2】:

正如@Biju 所说,模型属性参数是一个新对象,与模型中的对象分开。模型属性参数由页面数据填充,但不使用模型对象数据初始化。

必须将模型属性参数中的新数据复制到您已放入会话中的 bean 中。

【讨论】:

    猜你喜欢
    • 2012-01-31
    • 2013-04-27
    • 2013-07-15
    • 2011-06-09
    • 2014-07-06
    • 2019-01-08
    • 2011-07-01
    • 2018-09-19
    相关资源
    最近更新 更多