Baccello @ViewScoped ricreato su ogni richiesta di postback quando si utilizza JSF 2.2

Sto riscontrando un problema simile a questo post e la risposta di @BalusC con 3 soluzioni ma:

  • Non sto usando le espressioni EL menzionate
  • Non voglio andare con la seconda soluzione (è abbastanza complesso per me come questa)
  • e il salvataggio parziale dello stato è impostato su falso.

Il mio codice è il seguente:

index.xhtml :

     Insert title here    

...

MenusBean.java :

 package menus; import java.io.Serializable; import java.util.HashMap; import java.util.Map; import javax.faces.bean.ManagedBean; import javax.faces.bean.SessionScoped; import javax.faces.view.ViewScoped; @ManagedBean @ViewScoped public class MenusBean implements Serializable{ private static final long serialVersionUID = -7793281454064343472L; private String mainPage="sub1_menu1"; private Map active; public MenusBean(){ System.out.println("MenusBean created"); active = new HashMap(); active.put(mainPage, true); active.put("sub1_menu2", false); } public boolean activateMenu(String page){ active.put(mainPage, false); active.put(page, true); mainPage = page; for (Map.Entry e : active.entrySet()) System.out.println(e.getKey()+":"+e.getValue()); return true; } public Map getActive() { return active; } } 

Quando viene eseguito, ottengo:

 Menu creati da Bean
 Menu creati da Bean
 Menu creati da Bean

Come è causato e come posso risolverlo?

Questo,

 import javax.faces.view.ViewScoped; 

è l’annotazione specifica del CDI introdotta con JSF 2.2 , intesa per essere utilizzata in combinazione con l’annotazione di gestione del bean specifico del CDI @Named .

Tuttavia, stai utilizzando l’annotazione di gestione dei bean specifica JSF @ManagedBean .

 import javax.faces.bean.ManagedBean; 

Dovresti quindi utilizzare uno degli ambiti forniti dallo stesso pacchetto javax.faces.bean . Il diritto @ViewScoped è laggiù:

 import javax.faces.bean.ManagedBean; import javax.faces.bean.ViewScoped; @ManagedBean @ViewScoped public class MenusBean implements Serializable{ 

Se si utilizza la combinazione errata, il bean si comporta come un bean @RequestScoped e viene ricreato in ogni chiamata.

In alternativa, se il tuo ambiente supporta CDI (GlassFish / JBoss / TomEE con Weld, OpenWebBeans, ecc.), Puoi anche sostituire @ManagedBean con @Named :

 import javax.inject.Named; import javax.faces.view.ViewScoped; @Named @ViewScoped public class MenusBean implements Serializable{ 

Si consiglia di passare a CDI. Le annotazioni di gestione dei bean specifiche JSF sono candidate alla deprecazione nelle future versioni EE JSF / Java poiché tutto si sta lentamente spostando / unificando verso CDI.