¿Por qué JSF necesita guardar el estado de los componentes de la interfaz de usuario en el lado del servidor?
Porque HTTP no tiene estado y JSF tiene estado. El árbol de componentes JSF está sujeto a cambios dinámicos (programáticos). JSF simplemente necesita saber el estado exacto en el que se encontraba cuando el formulario se mostró al usuario final, de modo que pueda procesar con éxito todo el ciclo de vida de JSF en función de la información proporcionada por el árbol de componentes JSF original cuando el formulario se ha enviado de nuevo a el servidor. El árbol de componentes proporciona información sobre los nombres de los parámetros de solicitud, los convertidores / validadores necesarios, las propiedades del bean administrado enlazado y los métodos de acción.
¿Hasta qué momento JSF guarda el estado de los componentes de la interfaz de usuario en el lado del servidor y cuándo exactamente se elimina la información de estado del componente de la interfaz de usuario de la memoria del servidor?
Esas dos preguntas parecen reducirse a lo mismo. De todos modos, esto es específico de la implementación y también depende de si el estado se guarda en el servidor o en el cliente. Una implementación un poco decente lo eliminará cuando haya expirado o cuando la cola esté llena. Mojarra, por ejemplo, tiene un límite predeterminado de 15 vistas lógicas cuando el ahorro de estado se establece en sesión. Esto se puede configurar con el siguiente parámetro de contexto en web.xml
:
<context-param>
<param-name>com.sun.faces.numberOfLogicalViews</param-name>
<param-value>15</param-value>
</context-param>
Consulte también las preguntas frecuentes de Mojarra para conocer otros parámetros específicos de Mojarra y esta respuesta relacionada com.sun.faces.numberOfViewsInSession vs com.sun.faces.numberOfLogicalViews
A medida que un usuario que ha iniciado sesión en la aplicación navega por las páginas, ¿seguirá acumulándose el estado de los componentes en el servidor?
Técnicamente, eso depende de la implementación. Si está hablando de navegación de página a página (solo solicitudes GET), Mojarra no guardará nada en la sesión. Sin embargo, si son solicitudes POST (formularios con enlaces de comando / botones), Mojarra guardará el estado de cada formulario en la sesión hasta el límite máximo. Esto permite al usuario final abrir varios formularios en diferentes pestañas del navegador en la misma sesión.
O, cuando el ahorro de estado se establece en el cliente, JSF no almacenará nada en la sesión. Puede hacerlo mediante el siguiente parámetro de contexto en web.xml
:
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
Luego se serializará en una cadena encriptada en un campo de entrada oculto con el nombre javax.faces.ViewState
del formulario.
No entiendo cuál es el beneficio de mantener el estado del componente de la interfaz de usuario en el lado del servidor. ¿No es suficiente pasar directamente los datos validados / convertidos a beans administrados? ¿Puedo / debería intentar evitarlo?
Eso no es suficiente para garantizar la integridad y solidez de JSF. JSF es un marco dinámico con un único punto de control de entrada. Sin una administración estatal, uno podría falsificar / piratear solicitudes HTTP de cierta manera (por ejemplo disabled
, manipular readonly
y rendered
atributos), para permitir que JSF haga cosas diferentes y potencialmente peligrosas. Incluso sería propenso a ataques CSRF y phishing.
¿Y eso no consumirá demasiada memoria en el lado del servidor, si hay miles de sesiones de usuario simultáneas? Tengo una aplicación donde los usuarios pueden publicar blogs sobre ciertos temas. Estos blogs son bastante grandes. Cuando haya una publicación o una solicitud para ver los blogs, los blogs grandes se guardarán como parte del estado de los componentes. Esto consumiría demasiada memoria. ¿No es esto una preocupación?
La memoria es particularmente barata. Simplemente dé suficiente memoria al servidor de aplicaciones. O si el ancho de banda de la red es más económico para usted, simplemente cambie el ahorro de estado al lado del cliente. Para encontrar la mejor coincidencia, simplemente haga una prueba de estrés y cree un perfil de su aplicación web con la cantidad máxima esperada de usuarios concurrentes y luego dele al servidor de aplicaciones el 125% ~ 150% de la memoria máxima medida.
Tenga en cuenta que JSF 2.0 ha mejorado mucho en la gestión del estado. Es posible guardar el estado parcial (por ejemplo, solamente el <h:form>
se guardará en lugar de toda la materia de <html>
todo el camino hasta el final). Mojarra, por ejemplo, hace eso. Un formulario promedio con 10 campos de entrada (cada uno con una etiqueta y un mensaje) y 2 botones no ocuparía más de 1 KB. Con 15 vistas en sesión, eso no debería ser más de 15 KB por sesión. Con ~ 1000 sesiones de usuario simultáneas, eso no debería superar los 15 MB.
Su preocupación debería centrarse más en los objetos reales (beans gestionados y / o incluso entidades de base de datos) en el ámbito de la sesión o la aplicación. He visto muchos códigos y proyectos que duplican innecesariamente toda la tabla de la base de datos en la memoria de Java en el sabor de un bean con alcance de sesión donde se usa Java en lugar de SQL para filtrar / agrupar / organizar los registros. Con ~ 1000 registros, eso fácilmente superaría los 10 MB por sesión de usuario .