我了解@ModelAttribute吗?

时间:2011-11-09 21:54:40

标签: java spring java-ee

我需要帮助理解来自@ModelAttribute文档的Spring的以下示例:(方法populatePetTypes()

@Controller
@RequestMapping("/owners/{ownerId}/pets/{petId}/edit")
@SessionAttributes("pet")
public class EditPetForm {

    // ...

    @ModelAttribute("types")
    public Collection<PetType> populatePetTypes() {
        return this.clinic.getPetTypes();
    }

    @RequestMapping(method = RequestMethod.POST)
    public String processSubmit(
            @ModelAttribute("pet") Pet pet,
            BindingResult result, SessionStatus status) {

        new PetValidator().validate(pet, result);
        if (result.hasErrors()) {
            return "petForm";
        }
        else {
            this.clinic.storePet(pet);
            status.setComplete();
            return "redirect:owner.do?ownerId=" + pet.getOwner().getId();
        }
    }

}

我不喜欢这个像我们的Model对象可以在整个当前控制器中获得的额外“值”。这是真的吗?

我正在尝试通过将代码添加到我的控制器来进行一些测试:

@ModelAttribute("user")
public Integer getKod(){
    return new Integer(123321);
}

另一种方法是:

@RequestMapping("/register")
public String register(Map<String, Object> map, @ModelAttribute("user") MyUser user, BindingResult result) {
...
}

现在我尝试将“kod”显示在我的表单中:

<form:form method="post" action="" commandName="user">
(...)
        <form:label path="kod">kod</form:label>:
        <form:input path="kod"/>
(...)
</form:form>

但我得到了:

java.lang.IllegalArgumentException: java.lang.ClassCastException@229d7c57

请帮忙!

1 个答案:

答案 0 :(得分:3)

注释意味着不同的东西取决于你把它放在哪里。

方法上的

@ModelAttribute告诉Spring将方法的return vlaue放在Map下。它没有告诉它对该对象进行属性绑定。所以你要在Map中放置一个名为“user”的Integer。

参数上的

@ModelAttribute告诉Spring“使用此名称在地图中查找内容,并将其分配给此方法参数。”

因此,您将一个Integer放在名为“user”的地图中,然后要求Spring分配给MyUser类型的Object。当然不能将整数转换为MyUser!

我认为你混淆了经典MVC意义上的'Model',它是你的MyUser,使用Spring的ModelMap,它是所有数据,可以作为视图的一部分使用。当Spring控制器引用'Model'时,它表示与构建屏幕相关的所有事物的ModelMap。您的MyUser对象是该地图中的一个条目,但可能还有更多其他内容也是该屏幕的一部分。在Spring-ese中,我们经常将您的MyUser称为“表单备份对象”,因为它是表单的实际绑定目标。

例如,在您发布的代码段中,PetTypes的“类型”列表是Spring ModelMap的一部分。它是构建视图所需的参考数据。但它不是'Pet'对象的属性,它是表单支持对象。