jsf - sessionscope - @ViewScoped llama a @PostConstruct en cada solicitud de devolución
sessionscope jsf (1)
Esto no parece correcto. Estaba haciendo una limpieza de mi código y me di cuenta de esto. Cada solicitud de Ajax está @PostConstruct
el constructor y @PostConstruct
de mi bean @ViewScoped
. Incluso una simple paginación de base de datos lo está disparando.
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.
En otras palabras, su bean @ViewScoped
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.
Está utilizando Mojarra 2.1.17 o una versión anterior, y la vista contiene expresiones EL que vinculan una propiedad de bean con ámbito de vista a un atributo de etiqueta que se evalúa durante el tiempo de compilación de la vista . Los ejemplos son JSTL
<c:if>
,<c:forEach>
, etc. o JSF<ui:include>
,<x:someComponent id="#{...}"
,<x:someComponent binding="#{...}">
, etc. Esto es causado por un error en Mojarra ( problema 1492 ). Ver también ¿Por qué @PostConstruct devuelve la devolución de llamada cada vez que Bean está @ViewScoped? JSFEsto ya está solucionado en la versión 2.1.18 de Mojarra. Si no puede actualizar a una versión más nueva, la solución alternativa es deshabilitar el ahorro de estado parcial como se muestra a continuación en
web.xml
, consulte también JSTL en Facelets JSF2 ... ¿Tiene sentido?<context-param> <param-name>javax.faces.PARTIAL_STATE_SAVING</param-name> <param-value>false</param-value> </context-param>
O cuando solo desea orientar un conjunto específico de vistas 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 de la
id
del componente JSF o el atributo debinding
a una propiedad de bean con ámbito de vista 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. Ver también ¿Cómo funciona el atributo ''vinculante'' en JSF? ¿Cuándo y cómo se debe usar?Estás usando Mojarra 2.2.0, solo esa versión tiene un error (aún desconocido) para mantener el alcance de la vista que ya está fijado en 2.2.1, ver también el número 2912 . La solución es actualizar a una versión más nueva.
La anotación
@ViewScoped
se importa desde el paquete incorrecto. JSF ofrece dos anotaciones@ViewScoped
, una del paquetejavax.faces.bean
para beans administrados con JSF anotados con@ManagedBean
, y otra del paquetejavax.faces.view
para beans administrados CDI anotados con@Named
. Cuando la anotación del alcance del frijol no coincide con la anotación de gestión del frijol, el alcance del frijol real se convertirá en el alcance predeterminado del marco de gestión del frijol, que es@RequestScoped
en frijoles administrados JSF y@Dependent
en frijoles administrados CDI.Debe asegurarse de tener cualquiera de las siguientes construcciones y no mezclarlas, consulte también @ViewScoped bean recreado en cada solicitud de devolución de datos cuando se utiliza 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 {
La vista está (¿accidentalmente?) Marcada transitoria mediante
<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. Ver también ¿Cuál es la utilidad de la apatridia en JSF?La aplicación web está configurada con el parámetro de contexto
com.sun.faces.enableRestoreView11Compatibility
establecido entrue
en un intento incorrecto de "evitar"ViewExpiredException
. Con esteViewExpiredException
contexto, laViewExpiredException
nunca seViewExpiredException
, 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, diríjase a javax.faces.application.ViewExpiredException: La vista no se pudo restaurar .El classpath en tiempo de ejecución de la aplicación web está contaminado con múltiples versiones diferentes de JSF API 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 webapp
/WEB-INF/lib
. En caso de que esté utilizando 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 nuestra página wiki de JSF y la respuesta a esta pregunta relacionada: ¿Cómo instalar y configurar correctamente las bibliotecas de JSF a través de Maven? .Cuando usa PrimeFaces
<p:dialog>
, asegúrese de que<p:dialog>
tenga su propia<h:form>
y que no esté anidada en otra<h:form>
. Consulte también p: fileUpload dentro de p: diálogo que pierde los valores de @ViewScoped .Cuando combine PrimeFaces
FileUploadFilter
con PrettyFaces, asegúrese de queFileUploadFilter
también se ejecute en solicitudes PrettyFaces reescritas / reenviadas. Ver también ViewScoped bean reconstruido cuando FileUploadListener llamó usando PrettyFaces y Cómo usar PrimeFaces p: fileUpload? El método Listener nunca se invoca o UploadedFile es nulo / arroja un error / no se puede usar .Cuando usa 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. Ver también CDI ViewScope y PrettyFaces: múltiples llamadas a @PostConstruct (JSF 2.2) .