我有一个带有2个方法的控制器,它们通过@ModelAttribute批注返回相关对象:
@ModelAttribute("site")
public Site getSite(){
.....
return site;
}
@ModelAttribute("document")
public Document getDocument(){
.....
return document;
}
这些对象彼此关联,一个站点包含许多文档。此关系在JPA中映射。这两个对象都包含一个具有相同名称的字段,称为“ urlAlias”。使用以下freemarker标记在页面上编辑此字段:
<@spring.bind "document" />
....
<@spring.formInput "document.urlAlias" />
当我向控制器提交表单时,我使用以下语法检索文档对象:
@RequestMapping(method = RequestMethod.POST)
public ModelAndView create(@ModelAttribute("document") @Valid Document document, BindingResult documentResult,
@ModelAttribute("site") Site site, Model model){
...Do Stuff...
}
看来,即使我仅在Document对象中编辑了该字段的值,我在Document的urlAlias字段中输入的任何值也已在Site对象中设置。
我对这里发生的事情感到困惑。我是否通过在同一控制器中映射多个ModelAttribute来做某事?还有其他可能导致此行为的原因吗?
最佳答案
看来问题出在我控制器的create()方法中的site参数:
@ModelAttribute("site") Site site
删除将停止Spring绑定到该对象中的字段。对于未来的Google员工,我使用以下代码代替了create()方法中的Site对象:
if (!model.containsAttribute("site")) {
throw new IllegalArgumentException("Model must contain site attribute.");
}
Site site = (Site) model.asMap().get("site");
由此看来,在一个控制器中声明多个ModelAttribute可能很好,但是一次只能使用一个作为方法中的参数。