2012-01-31 26 views
16

Estoy usando JSF 2.0 con GlassFish 3.0.Método @PostConstruct llamado dos veces para la misma solicitud

Tengo el siguiente 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"); 
    } 
} 

Desde el archivo de overview.xhtml Voy a llamar a diferentes atributos o métodos de mi OverviewController.

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

Todo funciona muy bien, pero el problema está en el archivo de 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 

Como se puede ver, el método init() se llama dos veces en la misma petición por ninguna razón que lo que nunca . Por lo que sé, cualquier método anotado con PostConstruct se llama una vez por cada solicitud. ¿Me equivoco?

EDITAR: No AJAX se utiliza en la página. Comprobé el número de solicitudes con Firebug. Hay peticiones hechas de árboles:

  • 1.One para la javax.faces.resource (GET)
  • 2.One para el archivo css (GET)
  • 3.One de vista general .xhtml (GET)
+0

¿Estás decir ClassFish o GlassFish? – Kushan

+0

@Kushan GlassFish – Ionut

+0

¿Está realizando alguna llamada Ajax? Use FireBug o un complemento similar para averiguar cuántas solicitudes realiza realmente el navegador. – MrKiane

Respuesta

19

Eso puede suceder si usted tiene múltiples marcos de gestión de la misma clase de frijol P.ej. JSF y CDI, o JSF y Spring, o CDI y Spring, etc. Compruebe dos veces su configuración y anotaciones en el bean.

Eso también puede ocurrir si está usando CDI y está utilizando múltiples anotaciones @Named en toda la clase. Por ejemplo, un @Named directamente en la clase para registrarlo como un bean administrado y otro en un método getter @Produces. Debería preguntarse si es realmente necesario. También podría simplemente usar #{bean.someObject} en lugar de #{someObject}.

@Named 
@RequestScoped 
public class Bean { 

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

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

} 

Eso también puede suceder si su bean administrado extiende alguna clase abstracta que tiene a su vez también es un @PostConstruct en el método. Debe eliminar la anotación de ella.Alternativamente, usted debe hacer que el método init abstracto y no tienen @PostConstruct en el frijol de aplicación:

public abstract class BaseBean { 

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

    public abstract void init(); 

} 
+1

¡Gracias! No tengo marcos múltiples pero esto me ayudó a entender cuál era el problema. Todos mis ManagedBeans extienden un 'BaseController'. Este BaseController tiene un método '@PostConstruct init()' que pensé que sería anulado por los otros ManagedBeans 'PostConstruct init() '. Sin embargo, parece que se invocan ambos 'init()'. Todo tiene sentido ahora ... ¡Gracias! – Ionut

+0

No debería tener '@ PostConstruct' en la clase' BaseController'. Eliminarlo – BalusC

+0

@BalusC: Tengo una pequeña pregunta secundaria. En cuanto al uso de JSF y CDI en el mismo bean, si uso '@ Inject' para inyectar un bean CDI en' @ ManagedBean', ¿se llamará el método '@ PostConstruct' dos veces? No estoy seguro de cómo aplicar framework múltiple en el mismo bean. Pensé que el marco se decidió por el bean anotado con '@ ManagedBean',' @ Named', etc. –

3

es posible que el tanto init() método y @PostConstruct métodos están disparando y haciendo que este comportamiento. Intente cambiar el nombre del método init() y/o ponerlo private. Creo que esto puede estar relacionado con sus problemas:

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

También encontré un buen post sobre la depuración de los ciclos de vida de JSF aquí: Debug JSF lifecycle

+1

Esto no tiene sentido. Un bean gestionado JSF no es una implementación 'HttpServlet'. – BalusC

+0

Quería decir que, dependiendo de la configuración, puede causar confusión en el sistema e iniciar ambos métodos. Quizás fue una posibilidad remota. Gracias por tu aclaración. – MrKiane

+0

Intenté eliminar la anotación pero luego se ignoraría init(). Como BalusC dijo, parece que no hay un método init() en un bean gestionado. – Ionut

Cuestiones relacionadas