2012-01-31 15 views
16

Sto utilizzando JSF 2.0 con GlassFish 3.0.Metodo @PostConstruct chiamato due volte per la stessa richiesta

Ho il seguente Managed Bean:

@ManagedBean 
@RequestScoped 
public class OverviewController{ 

    private List<Event> eventList; 

    @PostConstruct 
    public void init(){ 
     System.out.println("=> OverviewController - init() - enter"); 

     System.out.println("=< OverviewController - init() - exit"); 
    } 
} 

Dal file del overview.xhtml sto chiamando attributi o metodi diversi dal mio OverviewController.

<ui:repeat var="event" value="#{overviewController.eventList}"> 
    ... 
</ui:repeat> 

Tutto funziona bene, ma il problema è il file di registro:

INFO: Enter : RESTORE_VIEW 1 
INFO: Exit : RESTORE_VIEW 1 

INFO: Enter : RENDER_RESPONSE 6 
INFO: => OverviewController - init() - enter 
INFO: => Overview Controller - updateSelectedTab() - enter 
INFO: =< Overview Controller - updateSelectedTab() - exit 
INFO: =< OverviewController - init() - exit 
INFO: => OverviewController - init() - enter 
INFO: => Overview Controller - updateSelectedTab() - enter 
INFO: =< Overview Controller - updateSelectedTab() - exit 
INFO: =< OverviewController - init() - exit 
INFO: Exit : RENDER_RESPONSE 6 

Come si può vedere, il metodo init() viene chiamato due volte nella stessa richiesta per nessun motivo che cosa così mai . Da quello che so, ogni metodo annotato con PostConstruct viene chiamato una volta ogni richiesta. Ho sbagliato?

MODIFICA: Nessun AJAX è utilizzato sulla pagina. Ho controllato il numero di richieste con firebug. Ci sono richieste albero fatto:

  • 1.One per il javax.faces.resource (GET)
  • 2.One collega per il file css (GET)
  • 3.one per una panoramica .xhtml (GET)
+0

Sei dire ClassFish o GlassFish? – Kushan

+0

@Kushan GlassFish – Ionut

+0

Stai eseguendo chiamate Ajax? Usa FireBug o simili per scoprire quante richieste il browser sta effettivamente facendo. – MrKiane

risposta

19

che può accadere se si dispone di più strutture che gestiscono lo stesso classe di fagioli Per esempio. JSF e CDI, o JSF e Primavera o CDI e Molla, ecc. Controllare di nuovo la configurazione e le annotazioni sul bean.

Ciò può anche accadere se si utilizza CDI e si utilizzano più annotazioni @Named in tutta la classe. Ad esempio, un @Named direttamente sulla classe per registrarlo come bean gestito e un altro su un metodo getter @Produces. Avresti bisogno di chiedersi se sia lo veramente necessario. Puoi anche utilizzare #{bean.someObject} anziché #{someObject}.

@Named 
@RequestScoped 
public class Bean { 

    @PostConstruct 
    public void init() { 
     // ... 
    } 

    @Named 
    @Produces 
    public SomeObject getSomeObject() { 
     // ... 
    } 

} 

Questo può accadere anche se il bean gestito estende una classe astratta che ha a sua volta anche una @PostConstruct sul metodo. Dovresti rimuovere l'annotazione da esso.In alternativa, si dovrebbe fare il metodo init astratto e non avere @PostConstruct sul fagiolo di attuazione:

public abstract class BaseBean { 

    @PostConstruct 
    public void postConstruct() { 
     init(); 
    } 

    public abstract void init(); 

} 
+1

Grazie! Non ho più quadri ma questo mi ha aiutato a capire quale fosse il problema. Tutti i miei ManagedBeans estendono un 'BaseController'. Questo BaseController ha un metodo '@PostConstruct init()' che pensavo sarebbe stato scavalcato dagli altri ManagedBeans 'PostConstruct init() '. Sembra però che sia chiamato 'init()'. Tutto ha senso ora .. Grazie! – Ionut

+0

Non dovresti avere '@ PostConstruct' nella classe' BaseController'. Rimuoverla. – BalusC

+0

@BalusC: ho una piccola domanda a parte. Per quanto riguarda l'uso di JSF e CDI sullo stesso bean, se uso '@ Inject' per iniettare un bean CDI in un' @ ManagedBean', il metodo '@ PostConstruct' sarà chiamato due volte? Non sono abbastanza sicuro di come applicare più framework sullo stesso bean. Ho pensato che il framework fosse deciso annotando il bean con '@ ManagedBean',' @ Named', ecc. –

3

e 'possibile che il sia init() metodo e @PostConstruct metodi stanno sparando e causando questo comportamento. Prova a cambiare il nome del metodo init() e/o mettendolo private. Penso che questo potrebbe essere correlato ai vostri problemi:

http://javahowto.blogspot.com/2011/07/servlet-init-method-vs-postconstruct.html

ho anche trovato un buon posto sul debug cicli di vita JSF qui: Debug JSF lifecycle

+1

Questo non ha senso. Un bean gestito JSF non è un'implementazione 'HttpServlet'. – BalusC

+0

Intendo dire che, a seconda della configurazione, il sistema può essere confuso e attivare entrambi i metodi. Forse era un colpo lungo però. Grazie per il chiarimento. – MrKiane

+0

Ho provato a rimuovere l'annotazione, ma in seguito l'init() sarebbe stato ignorato. Come ha detto BalusC sembra che non esista un metodo init() in un bean gestito. – Ionut

Problemi correlati