我了解@ModelAttribute吗?

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

 @Controller @RequestMapping("/owners/{ownerId}/pets/{petId}/edit") @SessionAttributes("pet") public class EditPetForm { // ... @ModelAttribute("types") public Collection 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 map, @ModelAttribute("user") MyUser user, BindingResult result) { ... } 

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

 
(...) kod
:
(...)

但我得到了:

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

请帮忙!

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

方法上的@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’对象的属性,它是表单支持对象。