Do czego służy Biblioteka Zasobów JSF i jak należy z niej korzystać?

JSF <h:outputStylesheet>, <h:outputScript> oraz <h:graphicImage> komponenty mają atrybut library. Co to jest i jak należy to stosować? Istnieje wiele przykładów w sieci, które używają go w następujący sposób ze wspólnym typem zawartości/pliku css, js i img (lub image) jako nazwa biblioteki w zależności od użytego tagu:

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

Jak to jest przydatne? Wartość library w tych przykładach wydaje się powtarzać to, co zostało już reprezentowane przez nazwę znacznika. Dla <h:outputStylesheet> opiera się na nazwie znacznika już oczywiste, że reprezentuje "biblioteka CSS". Jaka jest różnica z następujących, które również działa w ten sam sposób?

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

Również generowane wyjście HTML jest nieco inne. Z uwagi na ścieżkę kontekstową /contextname i FacesServlet mapowania na wzorze URL *.xhtml, pierwsza z nich generuje następujący kod HTML z nazwą biblioteki jako parametrem żądania:

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

Podczas gdy ten ostatni generuje następujący kod HTML z nazwą biblioteki tylko w ścieżce 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="" />
[18]}to drugie podejście sprawia, że z perspektywy czasu również bardziej sensowne niż poprzednie podejście. W jaki sposób atrybut library jest wtedy użyteczny?
Author: BalusC, 2012-08-16

1 answers

Właściwie, wszystkie te przykłady w sieci, w których wspólny typ zawartości / pliku, jak "js", "css"," img", itp jest używany jako nazwa biblioteki są mylące.

Przykłady świata rzeczywistego

Na początek przyjrzyjmy się, jak używają go istniejące implementacje JSF, takie jak Mojarra i MyFaces oraz biblioteki komponentów JSF, takie jak PrimeFaces i OmniFaces . Nikt z nich nie używa w ten sposób bibliotek zasobów. Używają go (pod kołdrą, przez @ResourceDependency lub UIViewRoot#addComponentResource()) w następujący sposób:

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

Powinno być jasne, że w zasadzie reprezentuje wspólną nazwę biblioteki / modułu / tematu, do której należą wszystkie te zasoby.

Łatwiejsza identyfikacja

W ten sposób o wiele łatwiej jest określić i odróżnić, skąd te zasoby należą i / lub pochodzą. Wyobraź sobie, że zdarzy ci się mieć primefaces.css zasób we własnej aplikacji webowej, w którym nadpisujesz / finetuning niektóre domyślne CSS PrimeFaces; jeśli PrimeFaces nie użyje nazwy własnej biblioteki primefaces.css, to nie zostanie załadowana własna PrimeFaces, ale dostarczona przez webapp, która złamie look ' n ' feel.

Również, gdy używasz niestandardowego ResourceHandler, można również zastosować bardziej precyzyjną kontrolę nad zasobami pochodzącymi z określonej biblioteki, gdy library jest używany we właściwy sposób. Jeśli wszystkie biblioteki komponentów użyłyby "js" dla wszystkich swoich plików JS, jak ResourceHandler kiedykolwiek rozróżnić, czy pochodzi z określonej biblioteki komponentów? Przykładami są OmniFaces CombinedResourceHandler oraz GraphicResourceHandler; sprawdź createResource() metoda, w której Biblioteka jest sprawdzana przed delegowaniem do następnego obsługi zasobów w łańcuchu. W ten sposób wiedzą, kiedy utworzyć CombinedResource lub GraphicResource w tym celu.

Należy zauważyć, że RichFaces zrobił to źle. Nie używało żadnej library w ogóle i homebrewed inną warstwę obsługi zasobów na nim i dlatego jest to niemożliwe, aby programowo zidentyfikuj zasoby RichFaces. Właśnie dlatego OmniFaces CombinedResourceHander musiałem wprowadzić hack oparty na odbiciu , aby i tak zadziałał z zasobami RichFaces.

Własne webapp

Twoja własna aplikacja webapp niekoniecznie potrzebuje biblioteki zasobów. Lepiej to pomiń.

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

Lub, jeśli naprawdę potrzebujesz go mieć, możesz po prostu nadać mu bardziej rozsądną wspólną nazwę, taką jak "default" lub jakaś firma nazwisko.

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

Lub, gdy zasoby są specyficzne dla jakiegoś szablonu Facelets, możesz również nadać mu nazwę szablonu, aby łatwiej było się ze sobą odnosić. Innymi słowy, jest to bardziej do celów autoprezentacji. Np. w pliku szablonu /WEB-INF/templates/layout.xhtml:

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

I /WEB-INF/templates/admin.xhtml plik szablonu:

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

Aby zobaczyć przykład z prawdziwego świata, sprawdź omnifaces showcase source code .

Lub, gdy chcesz podzielić się tymi samymi zasobami na wiele webapps i stworzyli "wspólny" projekt dla tego na podstawie tego samego przykładu, jak w ta odpowiedź , która z kolei jest osadzona jako Jar w /WEB-INF/lib webapp, a następnie odwołaj się do niego jako biblioteka (nazwa jest wolna do wyboru; biblioteki komponentów, takie jak OmniFaces i PrimeFaces również działają w ten sposób):

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

Wersjonowanie Biblioteki

Kolejną główną zaletą jest to, że możesz zastosować wersjonowanie biblioteki zasobów we właściwy sposób na zasobach dostarczanych przez własną aplikację webapp (to nie działa dla zasobów osadzonych w słoiku). W folderze library można utworzyć bezpośredni podfolder podrzędny o nazwie we wzorze \d+(_\d+)* oznaczającej wersję biblioteki zasobów.

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

Przy użyciu tego znacznika:

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

Wygeneruje to następujący kod HTML z wersją biblioteki jako parametr 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="" />

Tak więc, jeśli edytowałeś / aktualizowałeś jakiś zasób, wszystko, co musisz zrobić, to skopiować lub zmienić nazwę folderu z wersją na nową wartość. Jeśli masz kilka wersji folderów, a następnie JSF ResourceHandler będzie automatycznie obsługiwał zasób z najwyższego numeru wersji, zgodnie z regułami porządkowania numerycznego.

Tak więc, podczas kopiowania / zmiany nazwy resources/default/1_0/* folderu na resources/default/1_1/* Jak Następuje:

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

Wtedy ostatni przykład znaczników wygeneruje następujący kod 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="" />

Spowoduje to, że webbrowser zażąda zasobu bezpośrednio z serwera, zamiast pokazywać ten o tej samej nazwie z pamięci podręcznej, gdy adres URL ze zmienionym parametr jest wymagany po raz pierwszy. W ten sposób użytkownicy końcowi nie muszą wykonywać twardego odświeżania (Ctrl+F5 itd.), gdy chcą odzyskać zaktualizowany zasób CSS / JS.

Należy pamiętać, że wersjonowanie bibliotek nie jest możliwe dla zasobów zamkniętych w pliku JAR. Potrzebujesz niestandardowego ResourceHandler. Zobacz także jak używać wersji JSF dla zasobów w jar .

Zobacz też:

 240
Author: BalusC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:59