jsf - template - primefaces
¿Por qué JSF salva el estado del árbol del componente? (2)
Parece haber una diferencia entre el estado del frijol administrado y el estado del árbol del componente. Puede controlar el estado del bean administrado mediante el uso de anotaciones como @RequestScoped y @SessionScoped , pero parece que no puede elegir si el estado del árbol de componentes está guardado o no (aunque puede elegir si está guardado en el servidor o cliente) )
Parece que el estado del árbol de componentes solo debería ser necesario para la duración de una única solicitud como una estructura de datos temporal para ayudar a procesar una solicitud. Debería reconstruirse desde cero para cada solicitud. Con JSF 2.0, el ahorro de estado parcial mejora la situación porque solo se guardan los datos del formulario, pero no entiendo por qué es útil incluso formar datos a partir de la solicitud anterior.
Si su aplicación solo utiliza beans administrados de alcance de solicitud, especialmente no tiene sentido guardar el estado del árbol de componentes entre las solicitudes. Incluso si su aplicación tiene beans administrados de alcance de sesión, supondría que los beans administrados mantendrían el estado y el árbol de componentes aún no necesitaría tener ningún estado entre las solicitudes.
Añadiendo a la respuesta anterior, desde JSF 2.0 algo que se llama partial state saving
se usa por defecto.
El lenguaje de descripción de vista predeterminado en JSF (Facelets) crea todo el árbol de componentes del Faletto original después de cada solicitud e inicializa los componentes de sus atributos de etiqueta correspondientes. Luego marca el estado.
Cada cambio de estado posterior se recuerda como un cambio delta, y es este estado el que se está guardando. Tal vez resulte que simplemente no hay tales cambios, y luego el estado de vista está vacío (debido a un error, el estado nunca estuvo realmente vacío, pero eso se ha solucionado recientemente. Consulte http://java.net/jira/browse/JAVASERVERFACES-2203 para más detalles)
Entonces la gran pregunta es, ¿qué hay en este estado cuando no está vacío?
Como BalusC ya comentó, esto podría contener cambios dinámicos en el árbol de componentes. Esos cambios pueden iniciarse desde el respaldo de los beans o desde componentes estáticos. Un ejemplo simple del tipo de componente que realiza este cambio dinámico es un componente de tabla que crea componentes de columna secundarios en función del número real de columnas en un conjunto de datos.
Otro uso importante para el estado de vista es recordar los valores que se han cambiado dentro de los componentes, pero que no se han insertado en el modelo. Esto puede ser algo como presionar un interruptor en un componente del interruptor, mover un control deslizante en un componente de marcado, etc.
Un ejemplo particular es el componente viewParam
, que recuerda el parámetro de solicitud (parámetro de cadena de consulta para el parámetro POST GET o non-faces) con el que se inicializó. Consulte esto para obtener más información al respecto: http://arjan-tijms.omnifaces.org/2011/07/stateless-vs-stateful-jsf-view.html
También existe una fuerte relación con los componentes con estado que recuerdan el estado de la IU y la conversión o validación que falla. En este caso, los componentes de la interfaz de usuario recordarán los valores ingresados por el usuario y recordarán que hubo un error de conversión / validación.
Otro uso más para el estado es la optimización. Algunos componentes calculan valores que consideran caros de calcular y los almacenan en el estado de vista. Por ejemplo, los componentes de UIInput lo hacen después de la primera publicación posterior:
private boolean validateEmptyFields(FacesContext ctx) {
if (validateEmptyFields == null) {
ExternalContext extCtx = ctx.getExternalContext();
String val = extCtx.getInitParameter(VALIDATE_EMPTY_FIELDS_PARAM_NAME);
if (val == null) {
val = (String) extCtx.getApplicationMap().get(VALIDATE_EMPTY_FIELDS_PARAM_NAME);
}
if (val == null || "auto".equals(val)) {
validateEmptyFields = isBeansValidationAvailable(ctx);
} else {
validateEmptyFields = Boolean.valueOf(val);
}
}
return validateEmptyFields;
}
Después de que validateEmptyFields
se almacena en el estado de la vista, por lo que no tiene que volver a calcularse en los siguientes envíos de formularios. Una mejora sería si los usuarios pueden elegir entre volver a calcular o almacenar (la bien conocida optimización de espacio-tiempo).
El mismo concepto de estado es lo que ha plagado el desarrollo de aplicaciones web desde su concepción inicial. Todo el mundo quiere tener interacciones que sean esencialmente constantes, pero casi nadie quiere manejarlo o siquiera pensar en ello.
JSF ha estado tratando de proporcionar una respuesta aquí, pero obviamente no es perfecta y hay margen de mejora. La insistencia de JSF en poder restaurar el estado de la vista (incluso el estado de vista vacía) puede ser problemático, aunque como se mencionó en otra respuesta proporciona una protección implícita contra CSRF. JSF 2.2 obtendrá una protección CSRF más explícita (consulte, por ejemplo, http://arjan-tijms.omnifaces.org/p/jsf-22.html#869 ), por lo que tal vez veamos algunos cambios aquí en el futuro.
Tener una opción para desactivar el estado por componente y tener un enlace fácil para restaurar el estado en el caso de que el marco no pueda (como en ASP.NET) también podría ser útil.
Porque el árbol de componentes se puede modificar programáticamente según la solicitud inicial. Esto no es necesariamente reproducible en la solicitud posterior siempre que los datos del formulario deban procesarse.
Además, tengo la impresión de que usted piensa que el árbol de componentes también contiene los valores del modelo. Esto no es verdad. Solo contiene referencias (por lenguaje de expresión) a los valores del modelo (las propiedades del bean gestionado). El estado de vista no copia / duplica / contiene el estado del modelo. Es solo un árbol de componentes de UI puro. Tal vez su confusión se basa en esto. Tenga en cuenta que el término "datos del formulario" se debe interpretar como valores enviados y valores del modelo.