web-dev-qa-db-fra.com

À quoi sert la bibliothèque de ressources JSF et comment doit-elle être utilisée?

Les composants JSF <h:outputStylesheet> , <h:outputScript> et <h:graphicImage> ont un attribut library. Qu'est-ce que c'est et comment cela devrait-il être utilisé? Il existe de nombreux exemples sur le Web qui l'utilisent comme suit avec le contenu commun/type de fichier css, js et img (ou image) comme nom de bibliothèque en fonction sur l'étiquette utilisée:

_<h:outputStylesheet library="css" name="style.css" />
<h:outputScript library="js" name="script.js" />
<h:graphicImage library="img" name="logo.png" />
_

Comment est-ce utile? La valeur library dans ces exemples semble ne faire que répéter ce qui a déjà été représenté par le nom de la balise. Pour un _<h:outputStylesheet>_ c'est basé sur le nom de la balise déjà évident qu'il représente une "bibliothèque CSS". Quelle est la différence avec ce qui suit qui fonctionne également de la même manière?

_<h:outputStylesheet name="css/style.css" />
<h:outputScript name="js/script.js" />
<h:graphicImage name="img/logo.png" />
_

En outre, la sortie HTML générée est un peu différente. Avec un chemin de contexte de _/contextname_ et FacesServlet mappant sur un modèle d'URL de _*.xhtml_, le premier génère le code HTML suivant avec le nom de la bibliothèque comme paramètre de demande:

_<link rel="stylesheet" type="text/css" href="/contextname/javax.faces.resource/style.css.xhtml?ln=css" />
<script type="text/javascript" src="/contextname/javax.faces.resource/script.js.xhtml?ln=js"></script>
<img src="/contextname/javax.faces.resource/logo.png.xhtml?ln=img" alt="" />
_

Alors que ce dernier génère le code HTML suivant avec le nom de la bibliothèque juste dans le chemin de l’URI:

_<link rel="stylesheet" type="text/css" href="/contextname/javax.faces.resource/css/style.css.xhtml" />
<script type="text/javascript" src="/contextname/javax.faces.resource/js/script.js.xhtml"></script>
<img src="/contextname/javax.faces.resource/img/logo.png.xhtml" alt="" />
_

Avec le recul, cette dernière approche a également plus de sens que la première. Dans quelle mesure l'attribut library est-il utile?

222
BalusC

En fait, tous les exemples sur le Web où le type de contenu/fichier commun tel que "js", "css", "img", etc. est utilisé comme nom de bibliothèque sont trompeurs .

Exemples du monde réel

Pour commencer, examinons comment les implémentations JSF existantes telles que Mojarra et MyFaces et les bibliothèques de composants JSF telles que PrimeFaces et OmniFaces utilise le. Aucun d'entre eux n'utilise les bibliothèques de ressources de cette façon. Ils l'utilisent (sous les couvertures, par @ResourceDependency ou UIViewRoot#addComponentResource() ) de la manière suivante:

_<h:outputScript library="javax.faces" name="jsf.js" />
<h:outputScript library="primefaces" name="jquery/jquery.js" />
<h:outputScript library="omnifaces" name="omnifaces.js" />
<h:outputScript library="omnifaces" name="fixviewstate.js" />
<h:outputScript library="omnifaces.combined" name="[dynamicname].js" />
<h:outputStylesheet library="primefaces" name="primefaces.css" />
<h:outputStylesheet library="primefaces-aristo" name="theme.css" />
<h:outputStylesheet library="primefaces-vader" name="theme.css" />
_

Il devrait être clair que cela représente fondamentalement le nom commun de bibliothèque/module/thème auquel toutes ces ressources appartiennent communément.

Identification plus facile

De cette façon, il est beaucoup plus facile de spécifier et de distinguer l’origine et/ou la provenance de ces ressources. Imaginez que vous ayez une ressource _primefaces.css_ dans votre propre application Web dans laquelle vous écrasez/optimisez certains CSS par défaut de PrimeFaces; Si PrimeFaces n'utilisait pas un nom de bibliothèque pour son propre _primefaces.css_, alors le nom propre de PrimeFaces ne serait pas chargé, mais celui fourni par webapp, ce qui aurait pour effet de casser l'apparence.

En outre, lorsque vous utilisez un ResourceHandler personnalisé, vous pouvez également appliquer un contrôle plus détaillé sur les ressources provenant d'une bibliothèque spécifique lorsque library est utilisé correctement. Si toutes les bibliothèques de composants avaient utilisé "js" pour tous leurs fichiers JS, comment le ResourceHandler pourrait-il jamais distinguer s'il provient d'une bibliothèque de composants spécifique? Les exemples sont OmniFaces CombinedResourceHandler et GraphicResourceHandler ; Vérifiez la méthode createResource() dans laquelle la bibliothèque est vérifiée avant de déléguer au gestionnaire de ressources suivant dans la chaîne. De cette façon, ils savent quand créer CombinedResource ou GraphicResource à cette fin.

Il convient de noter que RichFaces s’est trompé. Il n'a pas utilisé library du tout et homebrewed une autre couche de gestion de ressources dessus, et il est donc impossible d'identifier par programme les ressources RichFaces. C'est exactement la raison pour laquelle OmniFacesCombinedResourceHander a dû introduire n hack basé sur la réflexion afin de le faire fonctionner de toute façon avec les ressources RichFaces.

Votre propre application web

Votre propre application Web n'a pas nécessairement besoin d'une bibliothèque de ressources. Vous feriez mieux de simplement l'omettre.

_<h:outputStylesheet name="css/style.css" />
<h:outputScript name="js/script.js" />
<h:graphicImage name="img/logo.png" />
_

Ou, si vous en avez vraiment besoin, vous pouvez simplement lui attribuer un nom commun plus judicieux, tel que "défaut" ou un nom de société.

_<h:outputStylesheet library="default" name="css/style.css" />
<h:outputScript library="default" name="js/script.js" />
<h:graphicImage library="default" name="img/logo.png" />
_

Ou, lorsque les ressources sont spécifiques à un modèle maître Facelets, vous pouvez également lui donner le nom du modèle afin de faciliter la mise en relation. En d'autres termes, c'est plus à des fins d'autodocumentation. Par exemple. dans un fichier modèle _/WEB-INF/templates/layout.xhtml_:

_<h:outputStylesheet library="layout" name="css/style.css" />
<h:outputScript library="layout" name="js/script.js" />
_

Et un fichier de modèle _/WEB-INF/templates/admin.xhtml_:

_<h:outputStylesheet library="admin" name="css/style.css" />
<h:outputScript library="admin" name="js/script.js" />
_

Pour un exemple concret, consultez le code source de la vitrine OmniFaces .

Ou bien, lorsque vous souhaitez partager les mêmes ressources sur plusieurs applications Web et que vous avez créé un projet "commun" basé sur le même exemple que dans cette réponse , qui est à son tour intégré sous forme de fichier JAR dans les applications Web. _/WEB-INF/lib_, puis référencez-la également en tant que bibliothèque (le nom est libre de votre choix; les bibliothèques de composants comme OmniFaces et PrimeFaces fonctionnent également de cette manière):

_<h:outputStylesheet library="common" name="css/style.css" />
<h:outputScript library="common" name="js/script.js" />
<h:graphicImage library="common" name="img/logo.png" />
_

Versioning de la bibliothèque

Un autre avantage principal est que vous pouvez appliquer la gestion correcte des versions de bibliothèque de ressources aux ressources fournies par votre propre application Web (cela ne fonctionne pas pour les ressources incorporées dans un fichier JAR). Vous pouvez créer un sous-dossier enfant direct dans le dossier de la bibliothèque avec un nom dans le modèle \d+(_\d+)* pour indiquer la version de la bibliothèque de ressources.

_WebContent
 |-- resources
 |    `-- default
 |         `-- 1_0
 |              |-- css
 |              |    `-- style.css
 |              |-- img
 |              |    `-- logo.png
 |              `-- js
 |                   `-- script.js
 :
_

Lorsque vous utilisez ce balisage:

_<h:outputStylesheet library="default" name="css/style.css" />
<h:outputScript library="default" name="js/script.js" />
<h:graphicImage library="default" name="img/logo.png" />
_

Cela générera le code HTML suivant avec la version de la bibliothèque sous le paramètre v:

_<link rel="stylesheet" type="text/css" href="/contextname/javax.faces.resource/css/style.css.xhtml?ln=default&amp;v=1_0" />
<script type="text/javascript" src="/contextname/javax.faces.resource/js/script.js.xhtml?ln=default&amp;v=1_0"></script>
<img src="/contextname/javax.faces.resource/img/logo.png.xhtml?ln=default&amp;v=1_0" alt="" />
_

Ainsi, si vous avez modifié/mis à jour une ressource, il vous suffit alors de copier ou de renommer le dossier de version dans une nouvelle valeur. Si vous avez plusieurs dossiers de version, JSF ResourceHandler servira automatiquement la ressource à partir du numéro de version le plus élevé, conformément aux règles de classement numérique.

Ainsi, lors de la copie/renommage du dossier _resources/default/1_0/*_ dans _resources/default/1_1/*_, procédez comme suit:

_WebContent
 |-- resources
 |    `-- default
 |         |-- 1_0
 |         |    :
 |         |
 |         `-- 1_1
 |              |-- css
 |              |    `-- style.css
 |              |-- img
 |              |    `-- logo.png
 |              `-- js
 |                   `-- script.js
 :
_

Ensuite, le dernier exemple de balisage générera le code HTML suivant:

_<link rel="stylesheet" type="text/css" href="/contextname/javax.faces.resource/css/style.css.xhtml?ln=default&amp;v=1_1" />
<script type="text/javascript" src="/contextname/javax.faces.resource/js/script.js.xhtml?ln=default&amp;v=1_1"></script>
<img src="/contextname/javax.faces.resource/img/logo.png.xhtml?ln=default&amp;v=1_1" alt="" />
_

Cela forcera le navigateur Web à demander la ressource directement au serveur au lieu d’afficher celle qui porte le même nom dans le cache, lorsque l’URL avec le paramètre modifié est demandé pour la première fois. Ainsi, les utilisateurs finaux ne sont pas obligés d'effectuer une actualisation matérielle (Ctrl + F5, etc.) lorsqu'ils doivent récupérer la ressource CSS/JS mise à jour.

Veuillez noter que la gestion des versions par bibliothèque n'est pas possible pour les ressources contenues dans un fichier JAR. Vous aurez besoin d'un ResourceHandler personnalisé. Voir aussi Comment utiliser le contrôle de version JSF pour les ressources dans jar .

Voir également:

249
BalusC