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? 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&v=1_0" />
<script type="text/javascript" src="/contextname/javax.faces.resource/js/script.js.xhtml?ln=default&v=1_0"></script>
<img src="/contextname/javax.faces.resource/img/logo.png.xhtml?ln=default&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&v=1_1" />
<script type="text/javascript" src="/contextname/javax.faces.resource/js/script.js.xhtml?ln=default&v=1_1"></script>
<img src="/contextname/javax.faces.resource/img/logo.png.xhtml?ln=default&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ż:
- JSF resource versioning
- Jsf2 Static buforowanie zasobów
- Struktura dla wielu projektów JSF ze współdzielonym kodem
- Specyfikacja JSF 2.0 - Rozdział 2.6 Obsługa zasobów
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