A cosa serve la libreria di risorse JSF e come deve essere utilizzata?


228

JSF <h:outputStylesheet>, <h:outputScript>ed <h:graphicImage>i componenti hanno un libraryattributo. Cos'è questo e come dovrebbe essere usato? Ci sono un sacco di esempi sul web, che lo usano come segue con il tipo di contenuto comune / lima css, jse img(o image) come nome di una libreria a seconda del tag utilizzato:

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

Come è utile? Il libraryvalore in quegli esempi sembra semplicemente ripetere ciò che è già stato rappresentato dal nome del tag. Per un <h:outputStylesheet>si basa sul nome del tag già evidente che rappresenta una "libreria CSS". Qual è la differenza con quanto segue che funziona allo stesso modo?

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

Inoltre, l'output HTML generato è leggermente diverso. Dato un percorso di contesto /contextnamee FacesServletmappatura su un modello URL di *.xhtml, il primo genera il seguente HTML con il nome della libreria come parametro di richiesta:

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

Mentre quest'ultimo genera il seguente HTML con il nome della libreria proprio nel percorso dell'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="" />

Il secondo approccio ha, con il senno di poi, anche più senso del precedente. In che modo l' libraryattributo è quindi utile?

Risposte:


256

In realtà, tutti quegli esempi sul web in cui il tipo di contenuto / file comune come "js", "css", "img", ecc. È stato usato come nome della biblioteca sono fuorvianti .

Esempi del mondo reale

Per iniziare, diamo un'occhiata a come le implementazioni JSF esistenti come Mojarra e MyFaces e le librerie di componenti JSF come PrimeFaces e OmniFaces lo usano. Nessuno di loro usa le librerie di risorse in questo modo. Lo usano (sotto le coperte, da @ResourceDependencyo UIViewRoot#addComponentResource()) nel modo seguente:

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

Dovrebbe essere chiaro che in sostanza rappresenta il nome della libreria / modulo / tema comune a cui appartengono comunemente tutte quelle risorse.

Identificazione più facile

In questo modo è molto più facile specificare e distinguere la provenienza e / o la provenienza di tali risorse. Immagina di avere una primefaces.cssrisorsa nella tua webapp in cui stai sovrascrivendo / perfezionando alcuni CSS predefiniti di PrimeFaces; se PrimeFaces non utilizzava il nome di una libreria per conto proprio primefaces.css, allora quello di PrimeFaces non sarebbe stato caricato, ma invece quello fornito da webapp, che avrebbe interrotto l'aspetto.

Inoltre, quando si utilizza un'abitudine ResourceHandler, è anche possibile applicare un controllo più preciso sulle risorse provenienti da una libreria specifica quando libraryviene utilizzato nel modo giusto. Se tutte le librerie dei componenti avrebbero usato "js" per tutti i loro file JS, come si ResourceHandlerdistinguerebbe mai se proviene da una libreria di componenti specifica? Esempi sono OmniFaces CombinedResourceHandlere GraphicResourceHandler; controlla il createResource()metodo in cui viene controllata la libreria prima di delegare al gestore delle risorse successivo nella catena. In questo modo sanno quando creare CombinedResourceo GraphicResourceper lo scopo.

Si noti che RichFaces ha sbagliato. Non ne usava libraryaffatto e produceva un altro livello di gestione delle risorse su di esso ed è quindi impossibile identificare a livello di programmazione le risorse RichFaces. Questo è esattamente il motivo per cui OmniFaces ha CombinedResourceHander dovuto introdurre un hack basato sulla riflessione per farlo funzionare comunque con le risorse RichFaces.

La tua webapp

La tua webapp non ha necessariamente bisogno di una libreria di risorse. Faresti meglio a ometterlo.

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

Oppure, se hai davvero bisogno di averne uno, puoi semplicemente dargli un nome comune più sensato, come "predefinito" o un nome di società.

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

Oppure, quando le risorse sono specifiche per alcuni template master di Facelets, puoi anche dargli il nome del template, in modo che sia più facile relazionarsi. In altre parole, è più per scopi di auto-documentario. Ad esempio in un /WEB-INF/templates/layout.xhtmlfile modello:

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

E un /WEB-INF/templates/admin.xhtmlfile modello:

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

Per un esempio reale, controlla il codice sorgente della vetrina OmniFaces .

Oppure, quando desideri condividere le stesse risorse su più webapp e hai creato un progetto "comune" per quello basato sullo stesso esempio di questa risposta che è a sua volta incorporato come JAR in webapp /WEB-INF/lib, quindi fai riferimento anche a libreria (il nome è gratuito a tua scelta; anche le librerie di componenti come OmniFaces e PrimeFaces funzionano in questo modo):

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

Controllo delle versioni della libreria

Un altro vantaggio principale è che puoi applicare il controllo delle versioni delle librerie di risorse nel modo giusto sulle risorse fornite dal tuo webapp (questo non funziona per le risorse incorporate in un JAR). È possibile creare una sottocartella figlio diretta nella cartella della libreria con un nome nel \d+(_\d+)*modello per indicare la versione della libreria di risorse.

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

Quando si utilizza questo markup:

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

Questo genererà il seguente HTML con la versione della libreria come vparametro:

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

Quindi, se hai modificato / aggiornato alcune risorse, tutto ciò che devi fare è copiare o rinominare la cartella della versione in un nuovo valore. Se si dispone di più cartelle di versione, JSF ResourceHandlerservirà automaticamente la risorsa dal numero di versione più alto, in base alle regole di ordinamento numeriche.

Quindi, quando si copia / rinomina la resources/default/1_0/*cartella resources/default/1_1/*come segue:

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

Quindi l'ultimo esempio di markup genererebbe il seguente HTML:

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

Questo costringerà il browser web a richiedere la risorsa direttamente dal server invece di mostrare quello con lo stesso nome dalla cache, quando viene richiesto per la prima volta l'URL con il parametro modificato. In questo modo agli utenti finali non è richiesto di eseguire un aggiornamento completo (Ctrl + F5 e così via) quando devono recuperare la risorsa CSS / JS aggiornata.

Si noti che il controllo delle versioni della libreria non è possibile per le risorse racchiuse in un file JAR. Avresti bisogno di un'abitudine ResourceHandler. Vedi anche Come utilizzare il versioning JSF per le risorse nel vaso .

Guarda anche:


2
È possibile utilizzare EL per la libreria? Quindi, se volessi avere risorse / default e risorse / feelingFroggyToday, potrei fare qualcosa di simile a library = "# {someLibraryHere}" mappare someLibraryHere sulla mia libreria scelta e non fare affidamento sul rinominare la directory delle risorse con una versione successiva ogni volta Volevo cambiarli.
gebuh,

Quando dici library = admin o libray = layout, quelle cartelle (admin e layout) sono nella cartella delle risorse?
Koray Tugay,

Umm. Balus molto interessante. Sto riscontrando un problema in un'app Web in cui il file theme.css appare vuoto durante il caricamento. Questo succede solo dopo varie ridistribuzioni (in JBOSS EAP). L'URL CSS è così: /javax.faces.resource/css/theme.css.xhtml?ln=default&v=3_3_0_130416 ed è dichiarato in questo modo: <h: outputStylesheet library = "default" name = "css / theme. css "target =" head "/>. Forse questo problema è legato a problemi di versione?
Ricardo Vila,

2
I caratteri consentiti per il valore libraryo qualcosa correlato ad esso sono cambiati tra mojarra 2.2.5 (2.2.5-jbossorg-3, wildfly 8.0) e 2.2.11 (2.2.11-jbossorg-1)? Non riesco a trovare nulla nei rilasci. Vedere stackoverflow.com/questions/35719808/...
Kukeltje

3
Grazie @BalusC. Sfortunatamente anche il Java EE 7 Tutorial di Oracle fornisce l'esempio sbagliato usando un nome di libreria cssnel capitolo 8.6 Risorse Web e facendo qualcosa di sbagliato con css e immagini nell'applicazione di esempio guessnumber-jsf .
Jesper,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.