我有一个带有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可能很好,但是一次只能使用一个作为方法中的参数。

10-04 14:13
查看更多