Sono passato attraverso la documentazione Spring e il codice sorgente e non ho ancora trovato risposta alla mia domanda.Associazione dati di una classe astratta in spring-mvc
Ho queste classi nel mio modello di dominio e voglio usarle come oggetti del modulo di supporto in 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;
....
}
mio regolatore:
@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";
}
....
}
Sulla UI devo forma dinamica per i diversi tipi di credenziali. La mia richiesta POST di solito si presenta come:
name name
credentials_type user_name
credentials.password password
credentials.username username
seguito viene generata un'eccezione se cerco di inviare richiesta al server:
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)
Il mio primo pensiero è stato quello di utilizzare @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;
}
Problema con questo approccio è che il metodo prepareUserAccountBean
viene chiamato prima di qualsiasi altro metodo (come listAccounts
) che non è appropriato.
Una soluzione efficace è quella di spostare sia prepareUserAccountBean
sia saveUserAccount
sul controller separato. Non suona bene: voglio che tutte le operazioni relative all'utente risiedano nella stessa classe di controller.
Qualsiasi soluzione semplice? Posso utilizzare in qualche modo DataBinder, PropertyEditor o WebArgumentResolver?
Grazie !!!!!
Puoi pubblicare il codice completo dalle tue classi di dominio? Mi piacerebbe vedere i tuoi costruttori. –
Mi sembra che questo sia più un problema di mappatura/serializzazione/conversione con il tuo database piuttosto che con la vista. Gli account vengono deserializzati correttamente negli oggetti corretti prima di essere inviati alla vista? – DavidA