2011-01-28 7 views
4

J'essaie JSF 2.0 (après avoir utilisé ICEfaces 1.8 pour les derniers mois) et j'essaie de comprendre pourquoi dans JSF 2.0 mon constructeur de beans de backing est appelé plusieurs fois. Le bean est censé être instancié une seule fois lors de sa création, mais le texte "Bean Initialized" s'affiche chaque fois que je clique sur le bouton de commande, indiquant qu'un nouvel objet Bean est instancié.JSF Backing Bean constructeur appelé plusieurs fois

La page de Facelet:

<?xml version='1.0' encoding='UTF-8' ?> 
<html xmlns="http://www.w3.org/1999/xhtml" 
     xmlns:h="http://java.sun.com/jsf/html"> 

    <h:body> 
     <div id="content"> 
      <h:form id="form"> 
       <h:commandButton value="Toggle" action="#{bean.toggleShowMe}"/> 
      </h:form> 


      <h:panelGrid rendered="#{bean.showMe}"> 
       <h:outputText value="Show me!"/> 
      </h:panelGrid> 
     </div> 
    </h:body> 
</html> 

La fève de support:

@ManagedBean 
@RequestScoped 
public class Bean { 
    private boolean showMe = false; 

    public boolean isShowMe() { 
     return showMe; 
    } 

    public void setShowMe(boolean showMe) { 
     this.showMe = showMe; 
    } 

    public void toggleShowMe(){ 
     System.out.println(showMe); 
     if(showMe==true){ 
      showMe=false; 
     }else{ 
      showMe=true; 
     } 
    } 
    /** Creates a new instance of Bean */ 
    public Bean() { 
     System.out.println("Bean Initialized"); 
    } 

} 

C'est tout ce qu'il est. Juste un test simple. Le même comportement se montre si j'utilise ICEfaces 2.0 et à la place du panelGrid J'utilise:

<ice:panelPopup visible="#{bean.showMe}"> 

J'apprécierais toute aide ici. Je suis incapable de l'expliquer.

Mise à jour: En réponse à Aba Dov, je @SessionScoped le bean, en supposant qu'il n'appellerait pas le constructeur à chaque requête et a rencontré le même comportement. Qu'est-ce que je rate?

+0

Si la session IS du composant est étendue, elle ne sera pas créée plus d'une fois par session - puisque cette méthode est largement utilisée, le bogue est probablement dans votre code, pas dans JSF; utilisez-vous @SessionScoped du bon package? (il y en a deux dans EE6). – fdreger

+0

fdreger-J'utilise javax.faces.bean.SessionScoped. Dois-je utiliser javax.enterprise.context.SessionScoped? – TheDream34

Répondre

6

Vous avez déclaré la fève à placer dans le cadre de la demande et vous tirer un nouveau chaque fois que la requête HTTP par le bouton de commande. Vraiment le haricot sera créé à chaque demande. Si vous voulez que le bean vive aussi longtemps que la vue elle-même (comme dans IceFaces sous les couvertures pour tout ce truc ajax), alors vous devez déclarer la vue du bean portée (c'est nouveau dans JSF 2.0) .

@ManagedBean 
@ViewScoped 
public class Bean implements Serializable {} 
+0

Merci pour l'explication! Ça marche. Toutes les suggestions pour un bon endroit pour oser sur ce qui est nouveau JSF 2.0? Les spécifications sont assez lourdes à lire. – TheDream34

+0

Faites également attention au code impliquant '' et une liste provenant d'un bean. Cela appellera le constructeur plusieurs fois même lorsque ViewScoped –

+0

@Chris: voir aussi http://stackoverflow.com/questions/2842401/jstl-cforeach-causes-viewscoped-bean-to-invoke-postconstruct-on-every-request/ 2842424 # 2842424 – BalusC

0

Le bean est appelé chaque fois qu'il y a une demande de la page.

lorsque vous cliquez sur <h:commandButton> le formulaire est soumis et une requête est envoyée au serveur

afin d'empêcher que vous pouvez utiliser <t:saveState> ou <a4j:keepAlive> balises pour votre été.

par exemple <a4j:keepAlive beanName="YourBean" />

ces balises stocke l'instance de haricot dans l'arborescence des composants.

assurez-vous également que votre classe implements Serializable. il peut donc être sérialisé

Hope this helps

+0

Dans JSF 2 le viewscope fait le travail de keepAlive ou saveState –

1

Le bean doit être dans ViewScoped.

+0

Que faire si vous n'avez pas besoin de conserver les données pendant si longtemps. ViewScoped fonctionne mais pas gratuitement, il consomme de la mémoire sur votre serveur, pourquoi avez-vous besoin de garder les données inutiles si longtemps? Étant donné que les données sont déjà demandées par le bean, la vue est déjà prise en compte. Pourquoi JSF doit-il déclencher la création de tous les beans gérés dans la vue lorsque le bouton commmandButton est enfoncé? le bean actionListener est instancié? –

Questions connexes