J'ai récemment commencé à utiliser JSF 2.0 avec Facelets et me suis laissé perplexe devant de nouveaux composants composites connaissant le <ui:include>
et autres techniques de modélisation proposées par Facelets 1.x.
Quelle est la différence entre ces approches? Fonctionnellement, ils semblent offrir à peu près la même chose: <ui:param>
contre <cc:attribute>
, <ui:insert>
+ <ui:define>
vs fichiers de balises, réutilisation des modèles existants. Existe-t-il autre chose que la syntaxe et une spécification d'interface claire dans le cas de composants composites? Les performances pourraient-elles différer?
Quelle est la différence entre ces approches?
Utilisez les modèles Facelet (comme dans <ui:composition>
, <ui:include>
et <ui:decorate>
) si vous souhaitez scinder des fragments de mise en page principale en modèles réutilisables. Par exemple. en-tête, menu, contenu, pied de page, etc.
Exemples:
Utilisez les fichiers de balises Facelet si vous souhaitez créer un groupe de composants réutilisable afin d’empêcher/réduire au minimum la duplication de code. Par exemple. un groupe de composants étiquette + entrée + message. La principale différence avec les composants composites est que la sortie d'un fichier de balises Facelet ne représente pas un seul UIComponent
et peut, dans certaines circonstances, être la seule solution lorsqu'un composant composite ne suffit pas. Généralement, avoir un <ui:include>
avec un ou plusieurs <ui:param>
qui transmet une propriété de bean géré (et donc pas une valeur codée en dur) indique que le fichier include peut être un fichier de balises.
Exemples:
Utilisez des composants composites si vous souhaitez créer un UIComponent
personnalisé unique et réutilisable avec une responsabilité unique en utilisant du XML pur. Un tel composant composite consiste généralement en un ensemble de composants existants et/ou HTML et est physiquement rendu sous la forme d'un composant unique. Il est supposé être lié à une propriété de bean unique. Par exemple. un composant qui représente un seul Java.util.Date
propriété par 3 dépendants <h:selectOneMenu>
composants, ou un composant qui combine <p:fileUpload>
et <p:imageCropper>
en un seul <my:uploadAndCropImage>
faisant référence à une seule coutume com.example.Image
entité en tant que propriété.
Exemples:
Utilisez un composant personnalisé chaque fois que la fonctionnalité ne peut pas être obtenue avec des fichiers de balises Facelet ou des composants composites, en raison du manque de prise en charge du jeu de composants standard/disponible. Des exemples peuvent être trouvés partout dans le code source de bibliothèques de composants open source telles que PrimeFaces et OmniFaces .
Lorsque vous souhaitez contrôler la construction de l'arborescence des composants JSF au lieu du rendu de la sortie HTML, vous devez utiliser un gestionnaire de balises au lieu d'un composant.
Exemples:
Voici quelques exemples de projets utilisant toutes les techniques mentionnées ci-dessus.
Les performances pourraient-elles différer?
Techniquement, le problème de performances est négligeable. Le choix doit être fait en fonction des exigences fonctionnelles concrètes et du degré final d'abstraction, de réutilisabilité et de maintenabilité de la mise en œuvre. Chaque approche a son propre but bien défini et ses limites.
Les composants composites ont toutefois une surcharge importante lors de la création/restauration de la vue (en particulier lors de la sauvegarde/restauration de l'état de la vue). De plus, dans les versions antérieures de Mojarra, les composants composites rencontraient des problèmes de performances lors de l'attribution de valeurs par défaut. Ce problème a déjà été résolu depuis 2.1.13. En outre, Mojarra avait un fuite de mémoire quand un <cc:attribute method-signature>
est utilisé pour les expressions de méthode. En principe, toute l’arborescence des composants est référencée dans la session HTTP. Cette situation est corrigée depuis 2.1.29/2.2.8. La fuite de mémoire peut être contournée dans les anciennes versions 2.1 comme ci-dessous:
<context-param>
<param-name>com.Sun.faces.serializeServerState</param-name>
<param-value>true</param-value>
</context-param>
Ou dans les anciennes versions 2.2 comme ci-dessous:
<context-param>
<param-name>javax.faces.SERIALIZE_SERVER_STATE</param-name>
<param-value>true</param-value>
</context-param>
Néanmoins, lorsque vous avez relativement "beaucoup" de composants composites et que vous avez javax.faces.STATE_SAVING_METHOD
réglé sur client
, la performance sera pénible. N'abusez pas des composants composites si vous voulez simplement les fonctionnalités de base déjà possibles avec un simple fichier include ou un fichier tag. Ne pas utiliser la facilité de configuration (lire: no *.taglib.xml
fichier nécessaire) comme excuse pour préférer les composants composites aux fichiers balises.
Lorsque vous utilisez Mojarra 2.2.10 ou une version plus ancienne, n'oubliez pas de désactiver la période d'actualisation relativement courte de Facelets pour le mode de production:
<context-param>
<param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name>
<param-value>-1</param-value>
</context-param>
N'utilisez pas ce paramètre pour le développement, sinon vous devrez redémarrer tout le serveur pour que les modifications apportées aux fichiers Facelets soient prises en compte! Mojarra 2.2.11 et plus récent, et MyFaces a déjà la valeur par défaut de -1
quand javax.faces.PROJECT_STAGE
n'est pas défini sur Development
.