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

JSF Java Discussion :

@ViewScoped ne sauvegarde pas durant la vue


Sujet :

JSF Java

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    146
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 146
    Points : 78
    Points
    78
    Par défaut @ViewScoped ne sauvegarde pas durant la vue
    Bonjour à tous,

    Je rencontre un problème avec un de mes beans qui est de type ViewScoped. Lors de son initialisation je sauvegarde / initialise plusieurs variables. Dans ma page xhtml je possède un bouton me dirigeant vers une autre page auquel j’associe un paramètre ; celui-ci est récupéré dans mon bean (et initialisé au tout début du bean). La variable n'est donc pas vide.

    Hors quand je change de page, cette nouvelle page va vouloir utiliser cette variable qui est soit disant null. Si je passe mon bean en SessionScoped aucun problème tout fonctionne. Néanmoins ce bean a pour vocation d’être en view, sa méthode postconstruct doit être appelé à chaque nouveau chargement.

    Je vous joins mes fichiers.

    Mon bouton :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    <h:commandButton value="Modifier" action="#{pageInstanceBean.modifier()}">
    	<ui:param name="instParam" value="#{pageInstanceBean.inst}"/>					  
    </h:commandButton>
    Mon bean :
    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
     
    import javax.faces.bean.ManagedBean;
    import javax.faces.bean.ViewScoped;
     
    @ManagedBean
    @ViewScoped
    public class PageInstanceBean implements Serializable
    {
    	private static final long serialVersionUID = 1L;
     
        //...
        private Instance inst;
     
        @PostConstruct
        public void init() 
        {
            FaceletContext faceletContext = (FaceletContext) FacesContext.getCurrentInstance().getAttributes().get(FaceletContext.FACELET_CONTEXT_KEY);
        	inst = (Instance) faceletContext.getAttribute("i");
     
    		//...
        }
     
    	//...
     
    	public String modifier()
    	{
    		return "instanceAdmin";
    	}
     
    	public Instance getInst() 
    	{
    		return inst;
    	}
    }
    J'avais cru comprendre qu'un viewscoped restait tant que l'on ne changeait pas de page. Est-ce moi qui ne comprend pas le fonctionnement d'un bean de type view, ou bien est-ce une erreur de codage ou autre ?

  2. #2
    Modérateur
    Avatar de Alkhan
    Homme Profil pro
    ingénieur full stack
    Inscrit en
    Octobre 2006
    Messages
    1 232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : ingénieur full stack

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 232
    Points : 2 061
    Points
    2 061
    Par défaut
    bonjour,

    Citation Envoyé par Lolosan Voir le message
    J'avais cru comprendre qu'un viewscoped restait tant que l'on ne changeait pas de page.
    la je dirais que tu as raison, ton bean est lié a ta vue !

    Citation Envoyé par Lolosan Voir le message
    Hors quand je change de page, cette nouvelle page va vouloir utiliser cette variable qui est soit disant null.
    Ba oui tu changes de page donc tu ne peux pas retrouver les données ajoutés dans une autre vue

    Je ne suis pas sur de comprendre ce qui te pose problème, le comportement que je pense avoir compris dans tes explications me semble normal !

    @ViewScoped : ton bean est lié a une vue, donc entre deux vues tu aura deux beans différents
    @SessionScoped : ton bean est lié à la session de l'utilisateur, donc il est partagé entre plusieurs vues d'une même session
    Il n'y a pas de problème, il n'y a que des solutions.
    Cependant, comme le disaient les shadoks, s'il n'y a pas de solution, c'est qu'il n'y a pas de problème.
    Si toutefois le problème persiste, la seule solution restante est de changer le périphérique qui se trouve entre la chaise et l'écran

    Mes Articles : Mon premier article est sur le language D
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    146
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 146
    Points : 78
    Points
    78
    Par défaut
    Ce que je souhaite : changer de page en envoyant un parametre.

    Dans mes log ce que je vois :
    - j'arrive sur ma page
    - passage dans ma fonction init
    - ma page est chargé je clique sur mon bouton
    - re passage dans ma fonction init...

    A ce niveau sa crash comme pas mal de mes variables on variés ^^. Enfin bref pour moi c'est pas normal. Ma vue est encore en cours.

    Pour moi sa devrait se dérouler comme sa :
    - j'arrive sur ma page
    - passage dans ma fonction init
    - ma page est chargé je clique sur mon bouton
    - le bouton charge ma variable
    - le bouton exécute sa fonction
    - changement de page
    - et la j'ai accès à ma variable dans un second bean lié à ma seconde page xhtml ou directement dans ma seconde page xhtml

    Apparemment vu mes log mon bean "meurt" après avoir chargé la page. Comme quand je clic sur le bouton il repasse par la fonction postconstruct... Pour moi le bean est sensé mourir dès que je quitte la page.

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    75
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 75
    Points : 54
    Points
    54
    Par défaut
    Voici le cycle de vie d'un bean @ViewScoped

    - appel à la page test1.xhtml
    - contruction de l'instance du bean TestBean1
    - appel à la méthode @PostConstruct de l'instance de TestBean1 si définie
    - affichage de la page test1.xhtml avec le contenu de l'instance de TestBean1
    - appel à la page test2.xhtml
    - appel à la méthode @PreDestroy de l'instance de TestBean1 si définie
    - destruction de l'instance du bean TestBean1
    - contruction de l'instance du bean TestBean2
    - appel à la méthode @PostConstruct de l'instance de TestBean2 si définie
    - affichage de la page test2.xhtml avec le contenu de l'instance de TestBean2

    Donc comme tu as changé de page, l'instance du bean TestBean1 a été détruite avant la contruction de l'instance du bean TestBean2 ; les 2 instances ne peuvent donc pas communiquer entre elles.
    Et si tu espères passer le contenu de ton ui:param d'une page à l'autre, c'est que tu n'as pas compris ui:param car ce n'est pas le cas.

  5. #5
    Membre chevronné
    Avatar de fxrobin
    Homme Profil pro
    Architecte SI, Java Fan, API Manager
    Inscrit en
    Novembre 2007
    Messages
    875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Architecte SI, Java Fan, API Manager
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2007
    Messages : 875
    Points : 2 112
    Points
    2 112
    Par défaut
    Bonjour,

    il existe plusieurs moyens pour passer des informations entre deux vues, et particulièrement entre leurs ManagedBeans.
    1 - Le session scope : c'est le côté obscur de la force, facile rapide, mais souvent une mauvaise idée car les données seront conservées en session et risque donc d'encombrer la mémoire pour rien.
    2 - le peuplement de propriétés du second managed bean avec le tag f:metadata. Cela nécessite de passer des paramètres soit en GET soit en POST à partir de la première page : http://mkblog.exadel.com/2010/07/lea...-page-actions/
    3 - le Flash Scope : sur une action ou actionListener dans le premier ManagedBean, on dépose dans le FlashScope (qu'on récupère auprès du contexte JSF). Ensuite en "PostConstruct" du second ManagedBean (de la seconde page) on va récupérer les informations dans le FlashScope. Tout reste "côté serveur".

    Personnellement j'apprécie le FlashScope. Ca durée de vie est simplement entre deux vues.
    Un tuto ici : http://jugojava.blogspot.fr/2011/06/...e-example.html
    Moins on code, moins il y a de bug ... et vice-versa ainsi qu'inversement ...

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    146
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 146
    Points : 78
    Points
    78
    Par défaut
    Merci beaucoup le FlashScope répond parfaitement à ce que je recherchais et en plus avec sa, sa résous un autre problème que j'avais (la redirection).

    Par contre si je peux encore vous embêter un peu j'ai un petit problème avec le FlashScope. Comme il est bien mieux que la façon que j'utilisais avant pour changer de page et envoyer des paramètres je voudrais modifier toutes mes pages. Seulement une me pose problème.

    C'est ma gestion d'un menu que je faisais de cette manière :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    <ui:repeat var="obj" value="#{monBean.listerObj}">
        <h:commandLink action="page2.xhtml" value="#{obj.nom}">
            <ui:param name="objParam" value="#{obj}">
        </h:commandLink>
    </ui:repeat>
    Comme mon menu est amené à évoluer au court du temps je dois le gérer plus ou moins de cette façon. Y aurait-il un moyen de faire intervenir le FlashScope avec une itération ?

  7. #7
    Membre chevronné
    Avatar de fxrobin
    Homme Profil pro
    Architecte SI, Java Fan, API Manager
    Inscrit en
    Novembre 2007
    Messages
    875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Architecte SI, Java Fan, API Manager
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2007
    Messages : 875
    Points : 2 112
    Points
    2 112
    Par défaut
    Bonjour,

    le FlashScope a pour objectif de passer des paramètres de page en page, entre 2 pages.
    Pour ton menu "dynamique" si c'est en fonction de l'utilisateur je mettrais ton ManagedBean qui gère le menu eventuellement en SessionScoped ou si c'est le même pour tous les utilisateurs je le mettrais en ApplicationScoped.

    En espérant avoir répondu à ta question.
    Moins on code, moins il y a de bug ... et vice-versa ainsi qu'inversement ...

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    146
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 146
    Points : 78
    Points
    78
    Par défaut
    En fait non sa me répond pas vraiment à ma question mais ce n'est pas grave. J'ai continué à chercher et j'ai finalement trouvé.

    Comme mon menu est une liste d'objet, si quelqu'un ajoute un objet il faut qu'il soit ajouté au menu ; c'est pourquoi j'ai laissé le bean gérant mon menu en view qui me parait plus adapté.

    Enfin bref pour passer une valeur d'une page à une autre avec FlashScope à l'intérieur d'une boucle j'ai fait comme sa :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    <h:form>
    	<ui:repeat var="obj" value="#{monBean.listerObj}">
    		<h:commandLink action="#{monBean.goTo}" actionListener="#{monBean.recupParam}" value="#{obj.nom}">
    			<f:attribute name="objParam" value="#{obj}">
    		</h:commandLink>
    	</ui:repeat>
    </h:form>
    On passe par une variable intermédiaire entre nos 2 beans de nos 2 pages.

    Le bean de ma premiere page :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    private Obj obj;
     
    public String goTo()
    {
    	Flash flash = FacesContext.getCurrentInstance().getExternalContext().getFlash();
    	flash.put("objParam", obj);
    	return "page2.xhtml?faces-redirect=true";
    }
     
    public void recupParam(ActionEvent event)
    {
    	obj = (Obj) event.getComponent().getAttributes().get("objParam");	
    }
    Et dans le bean de ma seconde page on recupere le parametre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    private Obj obj;
     
    @PostConstruct
    public void init() 
    {
    	Flash flash = FacesContext.getCurrentInstance().getExternalContext().getFlash();
    	obj = (Obj) flash.get("objParam");
    }
    Voili voilou. Merci beaucoup pour l'aide apportée !

  9. #9
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2012
    Messages : 3
    Points : 4
    Points
    4
    Par défaut une solution
    bonjour,
    je sais que je viens en retard http://www.developpez.net/forums/ima...s/icon_lol.gif
    mais j'ai une solution qui peut aider d'autres personnes:
    ---------------------------------------------------------
    la solution est toute simple: vous devez utiliser actionListiner a la place de action car elle va vous permettre d'envoyer vous bean après l’exécution de la méthode que vous avez préciser et ça va vous donner une large chois dans votre programmation *

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 20/10/2008, 00h16
  2. Réponses: 4
    Dernier message: 14/10/2008, 16h29
  3. J2EE Module Dependencies ne se sauvegardent pas
    Par gorilla dans le forum Eclipse Java
    Réponses: 5
    Dernier message: 22/05/2008, 10h26
  4. Réponses: 4
    Dernier message: 06/11/2006, 17h42
  5. XMLEncoder ne sauvegarde pas la donnée d'un PlainDocument.
    Par mitje dans le forum Format d'échange (XML, JSON...)
    Réponses: 1
    Dernier message: 27/01/2006, 04h06

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