it-swarm.com.de

Wozu dient die JSF-Ressourcenbibliothek und wie soll sie verwendet werden?

Die JSF <h:outputStylesheet> , <h:outputScript> und <h:graphicImage> Komponenten haben ein library Attribut. Was ist das und wie soll das verwendet werden? Es gibt viele Beispiele im Web, die es wie folgt verwenden: css, js und img (oder image) als Bibliotheksname abhängig vom verwendeten Tag:

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

Wie ist es nützlich? Der library -Wert in diesen Beispielen scheint nur das zu wiederholen, was bereits durch den Tag-Namen dargestellt wurde. Für ein <h:outputStylesheet> es basiert auf dem Tag-Namen, der bereits offensichtlich ist, dass es eine "CSS-Bibliothek" darstellt. Was ist der Unterschied zu dem Folgenden, das genauso funktioniert?

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

Auch die generierte HTML-Ausgabe ist etwas anders. Gegeben ein Kontextpfad von /contextname und FacesServlet Zuordnung zu einem URL-Muster von *.xhtml, ersteres generiert den folgenden HTML-Code mit dem Bibliotheksnamen als Anforderungsparameter:

<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="" />

Während letztere den folgenden HTML-Code mit dem Bibliotheksnamen nur im Pfad der URI generiert:

<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="" />

Der letztere Ansatz ist im Nachhinein auch sinnvoller als der erstere. Wie genau ist das library Attribut dann nützlich?

222
BalusC

Tatsächlich sind alle Beispiele im Web, in denen der allgemeine Inhalt/Dateityp wie "js", "css", "img" usw. als Bibliotheksname verwendet wird, irreführend.

Beispiele aus der Praxis

Schauen wir uns zunächst an, wie vorhandene JSF-Implementierungen wie Mojarra und MyFaces und JSF-Komponentenbibliotheken wie PrimeFaces und OmniFaces benutze es. Keiner von ihnen verwendet Ressourcenbibliotheken auf diese Weise. Sie verwenden es (unter dem Deckmantel von @ResourceDependency oder UIViewRoot#addComponentResource() ) auf folgende Weise:

<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" />

Es sollte klar werden, dass es im Grunde genommen den Namen common library/module/theme darstellt, zu dem all diese Ressourcen gehören.

Einfacher zu identifizieren

Auf diese Weise ist es viel einfacher zu spezifizieren und zu unterscheiden, woher diese Ressourcen gehören und/oder kommen. Stellen Sie sich vor, Sie haben zufällig eine primefaces.css - Ressource in Ihrer eigenen Webanwendung, in der Sie einige Standard-CSS von PrimeFaces überschreiben/optimieren. Wenn PrimeFaces keinen eigenen Bibliotheksnamen primefaces.css verwenden würde, würde nicht das PrimeFaces-eigene geladen, sondern das von der Web-App bereitgestellte, was das Look'n'Feel zerstören würde.

Wenn Sie ein benutzerdefiniertes ResourceHandler verwenden, können Sie auch die Kontrolle über Ressourcen aus einer bestimmten Bibliothek verfeinern, wenn library richtig verwendet wird . Wenn alle Komponentenbibliotheken "js" für alle ihre JS-Dateien verwendet hätten, wie würde das ResourceHandler jemals unterscheiden, ob es aus einer bestimmten Komponentenbibliothek stammt? Beispiele sind OmniFaces CombinedResourceHandler und GraphicResourceHandler ; Überprüfen Sie die createResource() -Methode, bei der die Bibliothek überprüft wird, bevor Sie sie an den nächsten Ressourcenhandler in der Kette delegieren. Auf diese Weise wissen sie, wann sie CombinedResource oder GraphicResource für diesen Zweck erstellen müssen.

Erwähnt werden sollte, dass RichFaces es falsch gemacht hat. Es wurde überhaupt kein library verwendet und eine andere Ebene für die Ressourcenverwaltung wurde darüber gebraut. Daher ist es unmöglich, RichFaces-Ressourcen programmgesteuert zu identifizieren. Genau aus diesem Grund musste OmniFacesCombinedResourceHandereinen reflexionsbasierten Hack einführen, damit es trotzdem funktioniert RichFaces-Ressourcen.

Deine eigene Webapp

Ihre eigene Webanwendung benötigt nicht unbedingt eine Ressourcenbibliothek. Am besten lassen Sie es einfach weg.

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

Oder, wenn Sie wirklich einen haben müssen, können Sie ihm einen vernünftigeren allgemeinen Namen geben, wie "default" oder einen Firmennamen.

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

Wenn die Ressourcen für eine Master-Facelets-Vorlage spezifisch sind, können Sie ihr auch den Namen der Vorlage geben, damit sich die Beziehungen einfacher gestalten. Mit anderen Worten, es ist eher für Selbstdokumentationszwecke. Z.B. in einer /WEB-INF/templates/layout.xhtml - Vorlagendatei:

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

Und eine Vorlagendatei /WEB-INF/templates/admin.xhtml:

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

Ein Beispiel aus der Praxis finden Sie in OmniFaces zeigt den Quellcode .

Oder wenn Sie die gleichen Ressourcen über mehrere Webapps hinweg gemeinsam nutzen möchten und ein "gemeinsames" Projekt dafür erstellt haben, das auf dem gleichen Beispiel wie in diese Antwort basiert und wiederum als JAR in die Webapps eingebettet ist /WEB-INF/lib, Dann bezeichnen Sie es auch als Bibliothek (der Name ist frei wählbar; Komponentenbibliotheken wie OmniFaces und PrimeFaces funktionieren auch so):

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

Versionierung der Bibliothek

Ein weiterer Hauptvorteil ist, dass Sie die Versionierung der Ressourcenbibliothek auf die von Ihrer eigenen Webanwendung bereitgestellten Ressourcen anwenden können (dies funktioniert nicht für in eine JAR eingebettete Ressourcen). Sie können einen direkten untergeordneten Unterordner im Bibliotheksordner mit einem Namen im Muster \d+(_\d+)* erstellen, um die Version der Ressourcenbibliothek anzugeben.

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

Wenn Sie dieses Markup verwenden:

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

Dadurch wird der folgende HTML-Code mit der Bibliotheksversion als v -Parameter generiert:

<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="" />

Wenn Sie also eine Ressource bearbeitet/aktualisiert haben, müssen Sie nur den Versionsordner kopieren oder in einen neuen Wert umbenennen. Wenn Sie über mehrere Versionsordner verfügen, wird die Ressource von JSF ResourceHandler automatisch mit der höchsten Versionsnummer gemäß den numerischen Ordnungsregeln bereitgestellt.

Wenn Sie also den Ordner resources/default/1_0/* In resources/default/1_1/* Kopieren/umbenennen, gehen Sie wie folgt vor:

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

Dann würde das letzte Markup-Beispiel den folgenden HTML-Code generieren:

<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="" />

Dadurch wird der Webbrowser gezwungen, die Ressource direkt vom Server anzufordern, anstatt die Ressource mit dem gleichen Namen aus dem Cache anzuzeigen, wenn die URL mit dem geänderten Parameter zum ersten Mal angefordert wird. Auf diese Weise müssen die Endbenutzer keine harte Aktualisierung durchführen (Strg + F5 usw.), wenn sie die aktualisierte CSS/JS-Ressource abrufen müssen.

Bitte beachten Sie, dass die Versionierung der Bibliothek für Ressourcen, die in einer JAR-Datei enthalten sind, nicht möglich ist. Sie benötigen ein benutzerdefiniertes ResourceHandler. Siehe auch Verwendung der JSF-Versionierung für Ressourcen in jar .

Siehe auch:

249
BalusC