【发布时间】:2011-04-05 02:56:14
【问题描述】:
我浏览了 Spring 文档和源代码,但仍未找到问题的答案。
我的域模型中有这些类,并希望将它们用作 spring-mvc 中的支持表单对象。
public abstract class Credentials {
private Long id;
....
}
public class UserPasswordCredentials extends Credentials {
private String username;
private String password;
....
}
public class UserAccount {
private Long id;
private String name;
private Credentials credentials;
....
}
我的控制器:
@Controller
public class UserAccountController
{
@RequestMapping(value = "/saveAccount", method = RequestMethod.POST)
public @ResponseBody Long saveAccount(@Valid UserAccount account)
{
//persist in DB
return account.id;
}
@RequestMapping(value = "/listAccounts", method = RequestMethod.GET)
public String listAccounts()
{
//get all accounts from DB
return "views/list_accounts";
}
....
}
在 UI 上,我有不同凭据类型的动态表单。我的 POST 请求通常如下所示:
name name
credentials_type user_name
credentials.password password
credentials.username username
如果我尝试向服务器提交请求,则会引发以下异常:
org.springframework.beans.NullValueInNestedPathException: Invalid property 'credentials' of bean class [*.*.domain.UserAccount]: Could not instantiate property type [*.*.domain.Credentials] to auto-grow nested property path: java.lang.InstantiationException
org.springframework.beans.BeanWrapperImpl.newValue(BeanWrapperImpl.java:628)
我最初的想法是使用@ModelAttribute
@ModelAttribute
public PublisherAccount prepareUserAccountBean(@RequestParam("credentials_type") String credentialsType){
UserAccount userAccount = new PublisherAccount();
Class credClass = //figure out correct credentials class;
userAccount.setCredentials(BeanUtils.instantiate(credClass));
return userAccount;
}
这种方法的问题是prepareUserAccountBean 方法在任何其他方法(如listAccounts)之前被调用,这是不合适的。
一个可靠的解决方案是将prepareUserAccountBean 和saveUserAccount 移出到单独的控制器。听起来不对:我希望所有与用户相关的操作都驻留在同一个控制器类中。
任何简单的解决方案?我可以以某种方式使用 DataBinder、PropertyEditor 或 WebArgumentResolver 吗?
谢谢!!!!!!
【问题讨论】:
-
您可以发布您的域类中的完整代码吗?我想看看你的构造函数。
-
在我看来,这更像是数据库的映射/序列化/转换问题,而不是视图。在发送到视图之前,帐户是否被正确反序列化为正确的对象?
标签: java spring data-binding spring-mvc binding