2011-04-04 37 views
24

Esto no parece correcto. Estaba haciendo una limpieza de mi código y me di cuenta de esto. Cada solicitud de Ajax está activando el constructor y @PostConstruct de mi bean @ViewScoped. Incluso una simple paginación de base de datos lo está disparando.@ViewScoped llama a @PostConstruct en cada solicitud de devolución

I understood que @ViewScoped es más largo que @RequestScoped y que no debe reconstruirse en cada solicitud. Solo después de una página completa de recarga por GET.

Respuesta

43

En otras palabras, su bean @ViewScoped se comporta como un bean @RequestScoped. Se ha vuelto a crear desde cero en cada solicitud de devolución. Hay muchas causas posibles para esto, la mayoría de las cuales se reduce a que la vista JSF asociada ya no está disponible en el estado JSF, que a su vez está asociado por defecto a la sesión HTTP.

Siempre que pueda asegurar que la sesión HTTP en sí misma no es la causa raíz del problema, es decir, cuando @SessionScoped funciona absolutamente bien, recorra la siguiente lista de posibles causas. De lo contrario, si la sesión HTTP en sí misma también se descarta y vuelve a crear en cada solicitud, deberá dar un paso atrás y observar la configuración de la cookie de sesión y del servidor. Cualquier causa relacionada con una sesión HTTP interrumpida está al menos más allá del contexto de JSF.

  1. Estás usando Mojarra 2.1.17 o más, y la vista contiene expresiones EL que se unen a fin de ámbito propiedad de bean a un atributo de etiqueta que se evalúa durante view build time. Los ejemplos son JSTL <c:if>, <c:forEach>, etc. o JSF <ui:include>, <x:someComponent id="#{...}", <x:someComponent binding="#{...}">, etc. Esto se debe a un error en Mojarra (issue 1492). Consulte también Why does @PostConstruct callback fire every time even though bean is @ViewScoped? JSF

    Esto ya está solucionado en la versión 2.1.18 de Mojarra. Si no se puede actualizar a una nueva versión, la solución consiste en deshabilitar el estado de parcial a ahorrar lo más adelante en web.xml, consulta JSTL in JSF2 Facelets... makes sense?

    <context-param> 
        <param-name>javax.faces.PARTIAL_STATE_SAVING</param-name> 
        <param-value>false</param-value> 
    </context-param> 
    

    O cuando se desea orientar un conjunto específico de sólo puntos de vista JSF:

    <context-param> 
        <param-name>javax.faces.FULL_STATE_SAVING_VIEW_IDS</param-name> 
        <param-value>/foo.xhtml;/bar.xhtml;/folder/baz.xhtml</param-value> 
    </context-param> 
    

    Es importante mencionar que vincular el valor del componente id o el atributo binding del componente JSF a una propiedad con vista de bean con ámbito es una mala práctica. Esos deberían estar realmente vinculados a una propiedad de bean con ámbito de solicitud, o se debería buscar una alternativa. Consulte también How does the 'binding' attribute work in JSF? When and how should it be used?

  2. Está utilizando Mojarra 2.2.0, solo esa versión tiene un error (aún desconocido) en el mantenimiento del alcance de la vista que ya se ha corregido en 2.2.1, consulte también issue 2912. La solución es actualizar a una versión más nueva.

  3. La anotación @ViewScoped se importa del paquete incorrecto. JSF ofrece dos anotaciones @ViewScoped, una del paquete javax.faces.bean para beans administrados con JSF anotados con @ManagedBean, y otra del paquete javax.faces.view para beans administrados CDI anotados con @Named. Cuando la anotación de alcance de bean no coincide con la anotación de gestión de bean, el alcance real de bean se convertirá en el alcance predeterminado de la gestión de bean, que es @RequestScoped en beans administrados JSF y @Dependent en beans administrados CDI.

    Debe asegurarse de tener cualquiera de las siguientes construcciones y no mezclarlas, consulte también @ViewScoped bean recreated on every postback request when using JSF 2.2.

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

    import javax.inject.Named; 
    import javax.faces.view.ViewScoped; 
    
    @Named 
    @ViewScoped 
    public class CorrectCDIViewScopedBean implements Serializable { 
    
  4. La vista es (accidentalmente?) Marcó transitoria a través de <f:view transient="true">. Esto básicamente enciende "JSF sin estado", que es nuevo desde Mojarra 2.1.19. De este modo, la vista JSF simplemente no se guardará en el estado JSF en absoluto y la consecuencia lógica es que todos los beans de ámbito de referencia a los que se hace referencia ya no pueden asociarse con la vista JSF. Véase también What is the usefulness of statelessness in JSF?

  5. La aplicación web está configurado con un conjunto parámetro com.sun.faces.enableRestoreView11Compatibility contexto de true en un intento erróneo de "evitar" ViewExpiredException. Con este parámetro de contexto, el ViewExpiredException nunca se arrojará, pero la vista (y todos los beans de ámbito de vista asociado) se recrearán desde cero. Sin embargo, si eso sucede en cada solicitud, este enfoque esconde otro problema: las vistas caducan demasiado pronto. Esto indica un posible problema en el mantenimiento de los estados de vista JSF y/o la sesión HTTP. Cómo resolverlo/configurarlo correctamente, vaya al javax.faces.application.ViewExpiredException: View could not be restored.

  6. El classpath en tiempo de ejecución de la aplicación web está contaminado con múltiples JSF API con versiones diferentes o clases relacionadas con impl. Esto causa una corrupción/falta de coincidencia en los identificadores/marcadores para el estado de vista JSF. Debe asegurarse de que no tiene varios archivos JAR de API JSF en el /WEB-INF/lib de webapp. En caso de que esté usando Maven, asegúrese de marcar las bibliotecas proporcionadas por el servidor como <scope>provided</scope>. Consulte también la sección "Instalación de JSF" en our JSF wiki page y la respuesta a esta pregunta relacionada: How to properly install and configure JSF libraries via Maven?.

  7. Al utilizar PrimeFaces <p:dialog>, a continuación, asegúrese de que el <p:dialog> tiene su propio <h:form> y que no está anidado en otro <h:form>. Vea también p:fileUpload inside p:dialog losing @ViewScoped values.

  8. Cuando se está combinando con PrimeFaces FileUploadFilter PrettyFaces, a continuación, asegúrese de que el FileUploadFilter corre también en PrettyFaces-reescritos/solicitudes remitidas. Consulte también ViewScoped bean rebuilt when FileUploadListener called using PrettyFaces y How to use PrimeFaces p:fileUpload? Listener method is never invoked or UploadedFile is null/throws an error/not usable.

  9. Cuando está utilizando PrettyFaces, una regla de reescritura mal configurada que redirige los recursos de CSS/JS/image a una página JSF vinculada a un bean @ViewScoped también dará un comportamiento engañoso. Vea también CDI ViewScope & PrettyFaces: Multiple calls to @PostConstruct (JSF 2.2).

+0

Su correcto. Agregué una función al sitio web que usa c: foreach en mi página. No es de extrañar que no lo haya notado antes. El problema es ui: repetir no funcionará en mi caso. http://primefaces.prime.com.tr/forum/viewtopic.php?f=3&t=59 ¿Funcionará el estado parcial de ahorro con la c: para cada uno? –

+0

Desafortunadamente no, deshabilitar el ahorro de estado parcial no resuelve el problema con las etiquetas JSTL. Este caso particular es sin embargo complicado. En teoría, puede resolver esto con un componente de plena capacidad, p. '' que acepta una colección en lugar de ''. Creo que esto fue publicado como una solicitud de función para PrimeFaces, no estoy seguro de lo que Cagatay hizo con él. – BalusC

+1

PARTIAL_STATE_SAVING cambió mi vida –

Cuestiones relacionadas