我需要帮助理解来自@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
请帮忙!
答案 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'对象的属性,它是表单支持对象。