¿Por qué JSF guarda el estado de los componentes de la interfaz de usuario en el servidor?

108
  1. ¿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? 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?

  2. No entiendo cuál es el beneficio de mantener el estado de los componentes de la interfaz de usuario en el servidor. ¿No es suficiente pasar directamente los datos validados / convertidos a beans administrados? ¿Puedo o debo intentar evitarlo?

  3. ¿No consume eso 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, ¿se guardarán los datos de esta página grande como parte del estado de los componentes? Esto consumiría demasiada memoria. ¿No es esto una preocupación?


Actualización 1:

Ahora, ya no es necesario guardar el estado mientras se usa JSF. Está disponible para su uso una implementación de JSF sin estado de alto rendimiento. Consulte este blog y esta pregunta para obtener detalles y discusiones relevantes. Además, hay un problema abierto para incluir en las especificaciones JSF, una opción para proporcionar el modo sin estado para JSF. (PD: Considere votar por los problemas esto y esto si esta es una característica útil para usted).


Actualización 2 (24-02-2013):

¡Una gran noticia que Mojarra 2.1.19 está disponible en modo sin estado !

Mira aquí:

http://weblogs.java.net/blog/mriem/archive/2013/02/08/jsf-going-stateless?force=255

http://java.net/jira/browse/JAVASERVERFACES-2731

http://balusc.blogspot.de/2013/02/stateless-jsf.html

Rajat Gupta
fuente

Respuestas:

199

¿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.ViewStatedel 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 readonlyy renderedatributos), 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 .

BalusC
fuente
1
¿Puede aclarar el n. ° 2? ¿Por qué no se puede volver a crear el árbol de componentes en cada solicitud? ¿Qué estado realmente debe almacenarse entre solicitudes y por qué? Parece que la única razón para guardar el árbol de componentes entre solicitudes sería el rendimiento.
Ryan
Pregunta más centrada aquí: stackoverflow.com/questions/7349174/…
Ryan
¡Tu respuesta fue muy clara para mí! ¡Los problemas sobre el rendimiento y la escalabilidad de JSF tienen una relación intrínseca con la implementación del programador! ¡Es necesario saber utilizar la tecnología de la manera correcta!
Lucas Batistussi
"Simplemente dé suficiente memoria al servidor de aplicaciones". Erm, tengo la impresión de que estamos hablando de cosas de nivel empresarial aquí, si estamos hablando de miles de sesiones de usuario simultáneas. Si tiene equipo de nivel empresarial en una empresa, no puede simplemente "darle al servidor de aplicaciones suficiente memoria" como puede hacerlo en su caja de Linux en casa.
Stu
Tu respuesta fue muy clara y gracias por eso. ¿Por qué desapareció el alcance flash JSF si se establece javax.faces.PARTIAL_STATE_SAVING en verdadero? getFacesContext (). getExternalContext (). getFlash (). put ("buildingId", buildingId).
May Thet