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 :

Spring MVC : Collision entre plusieurs "@ModelAttributes" ayant des propriétés de même nom


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 Spring MVC : Collision entre plusieurs "@ModelAttributes" ayant des propriétés de même nom
    Bonjour à tous,

    Je viens de me rendre compte d'un gros problème avec Spring MVC.
    J'ai un controlleur qui possède 2 méthodes annotées "@ModelAttribute" avec des classes différentes : "Project" et "Document".
    C'est 2 classes possède (entre autre) les propriété "id" et "reference".

    @ModelAttribute("project") est systématiquement appelé dans tous mes controlleurs "projet". Il récupère la référence du projet à partir de l'url et l'ajoute dans la session s'il est différent de celui déjà existant.

    Lorsque je POST mon formulaire d'édition d'un document, je me retrouve du coup avec @ModelAttribute("project") et @ModelAttribute("document") qui se suivent.
    Le problème c'est que ça génè-re des collisions : l'id de mon projet est égale à l'id du document, et la même chose pour la référence.

    Un bug ? Une erreur ? Une mauvaise pratique ?

    Comment corriger le problème ?

  2. #2
    Membre Expert
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 963
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 963
    Par défaut
    Version de Spring + le code pls.

    A priori, je soupçonnerais un mélange de 2 @Controller multi-action et @ModelAttribute sur des méthodes.

    S'il n'y a pas de @RequestMapping sur la classe @Controller, Spring ne peut sans doute pas limiter le scope des méthodes annotées @ModelAttribute.

  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
    Bonsoir,

    J'utilise spring 3.0.5. Je n'ai pas le code sur moi, je le posterai demain matin à la 1ère heure.
    En attendant voici l'architecture : J'ai eu classe abstraite AbstractProjectController, et une classe DocumentController qui hérite de AbstractProjectController.

    Il y a plusieurs modules pour un projet, dont une base documentaire. Chaque controller d'un module de projet hérite de AbstractProjectController.

    AbstractProjectController possède entre autre cette fameuse méthode qui est annotée "@ModelAttribute("project")" qui permet de récupérer le projet à partir d'une "path variable" de l'url.

    Je n'ai jamais eu de problème jusqu'à présent, mais je n'avais pas le scénario d'avoir 2 propriétés de même nom pour 2 modèle attribute différent...

  4. #4
    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
    Comme promis voici le code.

    AbstractProjectController :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public abstract class AbstractProjectController {
     
    	@Autowired
    	protected IProjectService projectSvc = null;
     
    	@ModelAttribute(MODEL_ATTR_CURRENT_PROJECT)
    	public Project getSessionCurrentProject(HttpServletRequest servletRequest){
     
    		//...
    		return sessionSelectedProject;
    	}
    }
    DocumentController :
    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    @Controller
    @RequestMapping("/projects/{projectRef}/documents/{documentId}")
    public class DocumentController extends AbstractProjectController {
     
    	//...
     
    	@ModelAttribute(ATT_KEY_DOCUMENT)
    	public AbstractDocument populateDocument(HttpServletRequest servletRequest){
     
    		//...
     
    		return document;
    	}
     
    	//...
     
    	@RequestMapping(value="/edit", method=RequestMethod.POST)
    	public String processSubmitEditDocumentForm(
    			ModelMap model,
    			@ModelAttribute(MODEL_ATTR_CURRENT_PROJECT) Project currentProject,
    			@ModelAttribute(ATT_KEY_DOCUMENT) SimpleDocument document,
    			@PathVariable(PATH_VAR_PROJECT_REF) String projectRef,
    			@PathVariable(PATH_VAR_DOCUMENT_ID) int documentId,
    			HttpServletRequest servletRequest){
     
    		/* Call the service */
    		try {
    			Project currentProject = getSessionCurrentProject(servletRequest);
    			librarySvc.saveDocument(currentProject, document);
     
    		} catch(Exception e){
    			e.printStackTrace();
    			model.addAttribute(ATT_KEY_MESSAGE_ERROR, e.getMessage());
    			return VW_PROJECT_DOCUMENT_FORM;
    		}
     
    		return "redirect:/projects/" + projectRef + "/documents/" + documentId;
    	}
    }

  5. #5
    Membre Expert
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 963
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 963
    Par défaut
    vous avez 2 fois @ModelAttribute(MODEL_ATTR_CURRENT_PROJECT)… donc il est appelé 2 fois…

    si vous avez une méthode @ModelAttribute(MODEL_ATTR_CURRENT_PROJECT), il ne faut rajouter un paramètre, en principe la méthode suffit…

    et si vous faites @Controller avec @RequestMapping, j'éviterais de rajouter @RequestMapping sur une méthode de ce controller pour changer l'URL, mais uniquement pour préciser method=RequestMethod

  6. #6
    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 JeitEmgie,

    Effectivement je n'ai plus ce phénomène de collision si je commente "@ModelAttribute(MODEL_ATTR_CURRENT_PROJECT) Project currentProject," dans DocumentController.processSubmitEditDocumentForm(), et que j'utilise "Project project = (Project) model.get(MODEL_ATTR_CURRENT_PROJECT);" à la place.

    Pourtant je pensais que c'était équivalent. J'ai vérifié avec des points d'arrêt, et la méthode annotée "@ModelAttribute(MODEL_ATTR_CURRENT_PROJECT)" est appelée 2 fois dans tous les cas.
    Sauf que si je mets "@ModelAttribute(MODEL_ATTR_CURRENT_PROJECT) Project currentProject" dans les paramètres alors qu'il y a déjà un "@ModelAttribute" avec une autre classe ayant des nom propriétés identiques, alors Spring prend les valeurs soumises par le modelAttribute du formulaire....

    Est-ce normal ? Existe-t-il un moyen d'y remédié ?

Discussions similaires

  1. [MVC] Spring Mvc vue avec plusieur boutons comment organiser le bean xml
    Par sgamette dans le forum Spring Web
    Réponses: 1
    Dernier message: 21/04/2011, 10h37
  2. Réponses: 4
    Dernier message: 23/10/2007, 09h14
  3. [Spring MVC] Plusieurs actions sur le même formulaire
    Par aloha dans le forum Spring Web
    Réponses: 3
    Dernier message: 26/08/2006, 15h22

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