com.sun.faces.numberOfViewsInSession vs com.sun.faces.numberOfLogicalViews

La implementación de Mojarra de JSF 2 tiene los siguientes parámetros de contexto:

  • com.sun.faces.numberOfViewsInSession (el valor predeterminado es 15)
  • com.sun.faces.numberOfLogicalViews (el valor predeterminado es 15)

¿Cuál es la diferencia entre ellos? La documentación no habla mucho sobre esto. Mi aplicación estaba teniendo problemas con ViewExpiredException para algunas páginas, pero después de cambiar estas configuraciones a un valor (mucho) más alto, dejamos de tener problemas.

Mi aplicación es una aplicación financiera, con gran cantidad de formularios y habilitada para AJAX (algunas pantallas tienen más de 50 entradas, con la opción de agregar muchos más datos / entradas a través de AJAX).

¿Cuál puede ser la causa de este comportamiento? Entiendo que el primer parámetro define la cantidad de “páginas” que se mantienen en sesión, lo que puede ser útil para el botón Atrás, pero mis casos de uso que desencadenan la ViewExpiredException no usan el botón Atrás. ¿A qué se refiere el segundo param? Si permanezco en la misma pantalla pero continúo agregando muchos datos a través de AJAX, ¿esto causa la necesidad de un mayor número de vistas lógicas para la página?

En primer lugar, la implementación de Mojarra cambió involuntariamente el significado de esos parámetros de contexto. Entonces, si tiene la impresión de que la descripción es exactamente al revés de lo que implica el nombre literal del parámetro de contexto, entonces esto es cierto.


com.sun.faces.numberOfLogicalViews

Esto es básicamente GET request based. Cada solicitud GET crea una nueva vista en sesión.

Para experimentar con él, ajústelo en un valor de 3, inicie una nueva sesión de navegador y abra 4 tabs diferentes del navegador (independientemente de la URL, puede ser la misma, puede ser diferente) en secuencia y luego vuelva a la primera pestaña y envíe la forma allí. Obtendrá una ViewExpiredException , porque esta vista se ha expulsado del mapa LRU (Utilizado menos recientemente) para las vistas en sesión. Esto no sucederá si abre un máximo de 3 tabs.

Con el valor predeterminado de 15, este es un raro problema del mundo real. Si su aplicación web está realmente diseñada para ser utilizada de esta manera (por ejemplo, un sitio social / comunitario que invita a abrirse en varias tabs, como foro de discusión o preguntas y respuestas), puede considerar usar el ahorro de estado del lado del cliente en lugar de boost el valor predeterminado . Con el ahorro del estado del lado del cliente, nunca enfrentará esta excepción. Una alternativa sería utilizar OmniFaces en combinación con un bean con ámbito de solicitud y parámetros de solicitud, o un bean de ámbito de vista que verifique (publique) construir si su propio estado necesita ser restaurado. Una vez más, otra alternativa es ir sin estado con , de esta forma las vistas ya no se guardan, pero ya no puede usar view scoped beans.

El equivalente de MyFaces es org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION cuyo valor predeterminado es 20.


com.sun.faces.numberOfViewsInSession

Esto es básicamente una solicitud POST síncrona (¡no ajax!). Cada solicitud POST síncrona crea una nueva vista lógica. Todos se almacenan en base a una vista física como Map> . Por lo tanto, con un máximo de 15 vistas físicas y un máximo de 15 vistas lógicas, teóricamente puede tener 15 * 15 = 225 vistas en sesión.

Para experimentar con él, configúrelo en un valor de 3, abra una vista con forma sincrónica, envíela 4 veces y luego presione el botón Atrás del navegador 4 veces y luego envíe el formulario nuevamente. Obtendrá una ViewExpiredException , porque esta vista se ha extraído del mapa LRU (Utilizado menos recientemente) para vistas lógicas. Esto no sucederá si vuelve al máximo 3 veces y luego vuelve a enviarlo.

Tenga en cuenta que ajax envía la reutilización de la misma vista lógica (puede confirmarla al ver exactamente el mismo valor de javax.faces.ViewState que se devuelve en javax.faces.ViewState de ajax). No hay soporte para el botón de retroceso del navegador de todos modos. El botón de retroceso del navegador solo lo regresa a la solicitud síncrona anterior, por lo tanto, no tendría ningún sentido almacenar todas las devoluciones de datos Ajax como vistas lógicas en sesión.

Con el valor predeterminado de 15 y la tendencia actual de los formularios de solo ajax y el caché desactivado en las páginas dinámicas, este es un problema muy raro en el mundo real. Los formularios debidamente diseñados no deberían invitar a presionar el botón Atrás del navegador. En su lugar, deben enviar correctamente la redirección a la vista de destino y, en caso de error, simplemente volver a mostrar el mismo formulario con errores de validación. Consulte para obtener sugerencias también ¿Cómo navegar en JSF? Cómo hacer que la URL refleje la página actual (y no la anterior) . Además, la caché está más que inhabilitada en las páginas dinámicas, por lo que el botón Atrás básicamente te da una nueva vista. Consulte también el botón Evitar retroceder en la aplicación web JSF . Si esto también es para su aplicación, puede establecer el valor de forma segura en 1.

MyFaces originalmente no tenía equivalente para esto, y contó esto como una vista física en sesión también. En la versión 2.0.6, se introdujo org.apache.myfaces.NUMBER_OF_SEQUENTIAL_VIEWS_IN_SESSION , con un propósito similar, aunque con una implementación diferente y por defecto desactivado.


Ver también:

  • ¿Por qué JSF guarda el estado de los componentes de la interfaz de usuario en el servidor?
  • ¿Debería PARTIAL_STATE_SAVING establecerse en falso?
  • javax.faces.application.ViewExpiredException: la vista no se pudo restaurar
  • ¿Cuál es la utilidad de la apatridia en JSF?

Acabo de encontrar esto en la web: http://oss.org.cn/ossdocs/java/ee/javaeetutorial5/doc/JSFConfigure11.html

Esto podría ser útil:

Las vistas lógicas son subvistas de una vista de nivel superior. Por ejemplo, si tiene una página que incluye varios marcos, entonces cada cuadro es una vista lógica. Si tiene una aplicación simple, el valor predeterminado de 15 vistas o 15 vistas lógicas puede ser demasiado grande. En este caso, debería considerar reducir el número permitido de vistas y vistas lógicas para conservar la memoria. Por el contrario, una aplicación más compleja puede requerir más de 15 vistas o vistas lógicas para ser guardadas en una sesión.