Ich bin durch Spring Dokumentation und Quellcode gegangen und habe immer noch keine Antwort auf meine Frage gefunden.Datenbindung einer abstrakten Klasse im Frühjahr-mvc
Ich habe diese Klassen in meinem Domänenmodell und möchte sie als Backing-Formularobjekte in Spring-MVC verwenden.
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;
....
}
Mein Controller:
@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";
}
....
}
Auf UI Ich habe dynamische Form für die verschiedenen Credential-Typen. Meine POST-Anfrage in der Regel wie folgt aussieht:
name name
credentials_type user_name
credentials.password password
credentials.username username
Nach Ausnahme wird ausgelöst, wenn ich versuche Anfrage an den Server zu übermitteln:
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)
Mein erster Gedanke war @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;
}
Problem zu verwenden, mit diesem Ansatz ist, dass prepareUserAccountBean
Methode aufgerufen werden, bevor andere Methoden (wie listAccounts
) auch, die nicht geeignet ist.
Eine robuste Lösung besteht darin, sowohl prepareUserAccountBean
als auch saveUserAccount
an den separaten Controller zu übertragen. Es klingt nicht richtig: Ich möchte, dass alle benutzerbezogenen Vorgänge in derselben Controller-Klasse liegen.
Eine einfache Lösung? Kann ich irgendwie DataBinder, PropertyEditor oder WebArgumentResolver verwenden?
Vielen Dank !!!!!
Können Sie den vollständigen Code aus Ihren Domain-Klassen veröffentlichen? Ich würde gerne Ihre Konstruktoren sehen. –
Hört sich für mich so an, als wäre das eher ein Mapping/Serialisierungs-/Konvertierungsproblem mit Ihrer Datenbank als mit der Ansicht. Werden die Konten korrekt in den richtigen Objekten deserialisiert, bevor sie an die Ansicht gesendet werden? – DavidA