IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Spring Web Java Discussion :

Fonctionnement de @ModelAttribute ? [@MVC]


Sujet :

Spring Web Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Avril 2005
    Messages
    307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Avril 2005
    Messages : 307
    Par défaut Fonctionnement de @ModelAttribute ?
    Bonjour à tous,

    Est-ce que quelqu'un pourrait m'expliquer le fonctionnement de l'annotation @ModelAttribute et comment l'utiliser (bonnes pratiques) ?

    Pour moi une méthode annotée @ModelAttribute est une méthode qui est appelée avant l'appel de la méthode @RequestMapping.
    Il permet notamment de faire passer un objet à une vue afin de populer un formulaire.

    J'ai l'impression que pour le retour d'un formulaire, il récupère l'objet du formulaire par cet intermédiaire, et lui affecte les nouvelles valeurs... Est-ce correct ?

    Soit la signature suivante (qui est tiré au hasard... de mon code ^^) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    @ModelAttribute("requirement_details")
    public RequirementDetails populateRequirementDetails(HttpServletRequest servletRequest)
    Dans cette méthode je renvois "new RequirementDetails()" si la méthode de la requete est "POST" (retour d'un formulaire) pour éviter d'effectuer une requête supplémentaire en base.
    Mon objet "RequirementDetails" possède une collection de "Compliance".
    Dans que la liste est vide à l'affichage du formulaire ET à sa soumission, tout se passe bien.
    Par contre lorsque la liste possède des éléments à l'affichage et que j'en supprime avant la soumission, j'ai une erreur
    Invalid property 'compliancesList[0]' [...] Cannot get element with index 0 from Set of size 0, accessed using property path 'compliancesList[0]'] with root cause
    On dirait qu'il fait un "setComplianceList[0] = <item de la liste>" au lieu de "setComplianceList = <ma nouvelle liste>"...

    Et moi ça m'embête

  2. #2
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Avril 2005
    Messages
    307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Avril 2005
    Messages : 307
    Par défaut
    Bonjour,

    Je suis allé voir du côté de AutoPopulateList, mais ça n'a pas l'air de fonctionner mieux.

    En fait j'ai l'impression qu'il ne prend pas en compte les modifications du formulaire, mais uniquement celles du ModelAttribute.
    Si dans ma méthode annotée @ModelAttribute je renvois "new RequirementDetails()" (avec un Set de Compliance vide) alors dans mon processSubmit je reçois un RequirementDetails avec une liste de Compliance vide, quelque soit ce que j'indique dans le formulaire.
    Si je renvois un RequirementDetails depuis la base de données (avec une Set de 2 Compliances), alors je reçois un RequirementDetails avec une liste de 2 Compliances...

    Voici ce que j'ai fais :
    Mon BO:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    public class RequirementDetails extends AbstractRequirement implements Cloneable {
    	private Set<Compliance> compliancesList = 
    		new HashSet<Compliance>();
     
    	public Collection<Compliance> getCompliancesList(){
    		List<Compliance> list = new AutoPopulatingList<Compliance>(Compliance.class);
    		list.addAll(compliancesList);
    		return list; 
    	}
     
    	public void setCompliancesList(Collection<Compliance> compliancesList){
    		this.compliancesList.clear();
     
    		for (Compliance complianceDetails : compliancesList) {
    			this.compliancesList.add(complianceDetails);
    		}
    	}	
     
    	//...
    }
    Ma méthode @ModelAttributes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    @ModelAttribute("requirement_details")
    public RequirementDetails populateRequirementDetails(HttpServletRequest servletRequest) 
    															throws NotFoundException{
    	RequirementDetails requirementDetails = null;
     
    	int requirementId = 0;
     
    	// Check if an id is given in a path variable
    	Map<?, ?> pathVariables =
    		(Map<?, ?>) servletRequest.getAttribute(
    				HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
     
    	if(pathVariables != null && pathVariables.containsKey("requirementId") 
    			&& servletRequest.getMethod() == "GET"){
    		requirementId = Integer.parseInt((String) pathVariables.get("requirementId"));
     
    		requirementDetails = 
    			this.planSvc.getRequirementDetailsById(requirementId);
    	}
    	// Else return new empty RequirementDetails
    	else{
    		requirementDetails = new RequirementDetails();
    	}
     
    	return requirementDetails;
    }
    Ma méthode "processSubmit" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public @ResponseBody RequirementDetails submitRequirementDetailsFormNew(
    		@ModelAttribute("requirement_details") RequirementDetails requirementDetails,
    		HttpServletRequest servletRequest) {
     
    }

  3. #3
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Avril 2005
    Messages
    307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Avril 2005
    Messages : 307
    Par défaut
    Je viens de m'apercevoir que dans mon getter getCompliancesList(), je copie RequirementDetails.compliancesList dans une nouvelle liste puis je retourne cette nouvelle liste.
    Donc il est normal que les ajouts/suppressions ne soient pas répercutées dans mon objet RequirementDetails.


    RequirementDetails.compliancesList est du type Set<Compliance>. Je pourrais le remplacer par AutoPopulating<Compliance>, mais je perdrais l'intérêt des Set avec Hibernate (--> suppression des doublons).

    Comment faire dans ce cas ?

  4. #4
    Membre très actif
    Inscrit en
    Juin 2005
    Messages
    210
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 210
    Par défaut
    Pourrais tu mettre le code de ton formulaire ? tu utilise bien les tag spring ?

    je te conseille de regarder ce lien qui est pas mal :
    http://www.mkyong.com/spring-mvc/spr...ation-example/

  5. #5
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Avril 2005
    Messages
    307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Avril 2005
    Messages : 307
    Par défaut
    Bonjour Garthos,

    Je n'ai plus le formulaire. J'ai résolu le problème divisant le "gros" formulaire.

    Du coup je me retrouve avec 3 formulaires moins complexes et je n'ai plus l'utilité du java.util.Set<E>.

    Merci pour ton retour (j'ai mis ton lien dans mes favoris

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 16/06/2003, 16h51
  2. Réponses: 5
    Dernier message: 14/05/2003, 14h51
  3. [Turbo Pascal] TP7 fonctionne en QWERTY
    Par callahan dans le forum Turbo Pascal
    Réponses: 9
    Dernier message: 08/02/2003, 21h49
  4. Prb de fonctionnement dans SaveDialog avecInitialDir
    Par boyerf dans le forum Composants VCL
    Réponses: 4
    Dernier message: 12/12/2002, 21h46
  5. ca ne fonctionne pas (generateur auto-incrémentant)
    Par tripper.dim dans le forum SQL
    Réponses: 7
    Dernier message: 26/11/2002, 00h10

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo