jsf-2 - plantillas - ui define
Cuándo usar<ui: include>, archivos de etiquetas, componentes compuestos y/o componentes personalizados? (1)
Empecé a usar JSF 2.0 con Facelets recientemente y me desconcertaron los nuevos componentes compuestos que conocen las <ui:include>
y otras técnicas de creación de plantillas que ofrece Facelets 1.x.
¿Cuál es la diferencia entre esos enfoques? Funcionalmente parecen ofrecer casi lo mismo: <ui:param>
vs <cc:attribute>
, <ui:insert>
+ <ui:define>
vs tag files, reutilización de las plantillas existentes. ¿Hay algo más que la sintaxis y la especificación de interfaz clara en el caso de componentes compuestos? ¿Podría el rendimiento diferir?
¿Cuál es la diferencia entre esos enfoques?
Plantillas de Facelet
Utilice plantillas de Facelet (como en <ui:composition>
, <ui:include>
y <ui:decorate>
) si desea dividir fragmentos de diseño de página principal en plantillas reutilizables. Ej. Encabezado, menú, contenido, pie de página, etc.
Ejemplos:
- ¿Cómo incluir otro XHTML en XHTML usando JSF 2.0 Facelets?
- ¿Cuál es la diferencia conceptual real entre ui: decorate y ui: include?
- Cómo personalizar h: head cuando usas ui: template de composición?
- Cómo cambiar los elementos principales de una página al usar ui: composición
- ¿Cómo ajax-refresh dinámico incluye contenido por menú de navegación? (JSF SPA)
Archivos de etiquetas de Facelet
Utilice los archivos de etiquetas de Facelet si desea tener un grupo reutilizable de componentes para evitar / minimizar la duplicación de código. Por ejemplo, un grupo de componentes etiqueta + entrada + mensaje. La principal diferencia con los componentes compuestos es que la salida de un archivo de etiqueta de Facelet no representa un único UIComponent
y, en algunas circunstancias, puede ser la única solución cuando un componente compuesto no es suficiente. En general, tener un <ui:include>
con uno o más <ui:param>
es una señal de que el archivo de inclusión puede ser mejor un archivo de etiqueta.
Ejemplos:
- ¿Cómo crear una etiqueta Facelets personalizada?
- ¿Cómo hacer una grilla del componente compuesto JSF?
- ¿Cómo crear un componente compuesto para una columna de tabla de datos?
- Primefaces outputLabel para componente compuesto
Componentes compuestos
Utilice componentes compuestos si desea crear un UIComponent
personalizado único y reutilizable con una sola responsabilidad utilizando XML puro. Tal componente compuesto por lo general consiste en un conjunto de componentes existentes y / o HTML y se procesa físicamente como un solo componente y se supone que está ligado a una única propiedad de bean. Por ejemplo, un componente que representa una sola propiedad java.util.Date
por 3 componentes <h:selectOneMenu>
, o un componente que combina <p:fileUpload>
y <p:imageCropper>
en un solo <my:uploadAndCropImage>
refiriendo un solo com.example.Image
personalizado com.example.Image
Entidad de imagen como propiedad.
Ejemplos:
- Nuestra página wiki de componentes compuestos
- El código BalusC: Componente compuesto con múltiples campos de entrada
- Dividir java.util.Date en dos h: campos de entrada de texto que representan hora y minuto con f: convertDateTime
- Seleccionar todos los elementos en Multiple SelectManyCheckBox con identificadores dinámicos
- Se extiende el componente JSF commandLink
- Evitar identificadores duplicados al reutilizar composiciones de facelets en el mismo contenedor de nombres
Componentes personalizados
Utilice un componente personalizado siempre que la funcionalidad no se pueda lograr con los archivos de etiquetas de Facelet o los componentes compuestos, debido a la falta de soporte en el conjunto de componentes estándar / disponibles. Se pueden encontrar ejemplos sobre todos los lugares del código fuente de bibliotecas de componentes de código abierto como PrimeFaces y OmniFaces .
Controladores de etiqueta
Cuando desee controlar la construcción del árbol de componentes JSF en lugar de renderizar el resultado HTML, deberá usar un controlador de etiquetas en lugar de un componente.
Ejemplos:
- Componente Custom Facelet en JSF
- ¿Cómo puedo acceder al contenido de algo creado con <ui: define> programáticamente?
- Conditional render en tagfile dependiendo de si el atributo está especificado o no
- Realización de una redirección cuando falla la conversión / validación asociada a los parámetros de consulta
Proyectos de ejemplo
Aquí hay algunos proyectos de ejemplo que utilizan todas las técnicas mencionadas anteriormente.
- Aplicación Java EE Kickoff ( templates - includes - tagfiles - composite )
- Escaparate de OmniFaces ( templates - includes - tagfiles - composite )
¿Podría el rendimiento diferir?
Técnicamente, la preocupación por el rendimiento es insignificante. La elección debe hacerse en función de los requisitos funcionales concretos y el grado final de abstracción, reutilización y mantenimiento de la implementación. Cada enfoque tiene su propio propósito y limitaciones bien definidos.
Sin embargo, los componentes compuestos tienen una sobrecarga significativa durante la construcción / restauración de la vista (específicamente: durante el almacenamiento / restauración del estado de la vista). Y, en versiones anteriores de Mojarra, los componentes compuestos tenían problemas de rendimiento con la asignación de valores predeterminados, esto ya está solucionado desde 2.1.13. Además, Mojarra tenía una pérdida de memoria cuando se utilizaba un <cc:attribute method-signature>
para las expresiones de métodos, básicamente todo el árbol de componentes se vuelve a referenciar en la sesión HTTP, esto es fijo desde 2.1.29 / 2.2.8. La fuga de memoria se puede omitir en las versiones anteriores de 2.1 como a continuación:
<context-param>
<param-name>com.sun.faces.serializeServerState</param-name>
<param-value>true</param-value>
</context-param>
O en las versiones anteriores de 2.2 como a continuación:
<context-param>
<param-name>javax.faces.SERIALIZE_SERVER_STATE</param-name>
<param-value>true</param-value>
</context-param>
Aún así, cuando tiene relativamente "muchos" componentes compuestos, y tiene javax.faces.STATE_SAVING_METHOD
configurado para el client
, entonces el rendimiento será un problema. No abuse de los componentes compuestos si solo desea la funcionalidad básica que ya es posible con un simple archivo de inclusión o un archivo de etiqueta. No utilice la facilidad de configuración (léase: no se necesita el archivo *.taglib.xml
) como excusa para preferir los componentes compuestos a los archivos de etiquetas.
Cuando utilice Mojarra 2.2.10 o una versión anterior, no olvide deshabilitar el período de actualización de Facelets relativamente corto para el modo de producción:
<context-param>
<param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name>
<param-value>-1</param-value>
</context-param>
No use esta configuración para el desarrollo; de lo contrario, debe reiniciar todo el servidor para que se reflejen los cambios en los archivos Facelets. Mojarra 2.2.11 y versiones posteriores, y MyFaces ya está predeterminado en -1
cuando javax.faces.PROJECT_STAGE
no está configurado en Development
.