На самом деле, все эти примеры в Интернете, где в качестве имени библиотеки используется общий тип содержимого / файла, такой как «js», «css», «img» и т. Д., Вводят в заблуждение .
Примеры из реального мира
Для начала давайте посмотрим, как его используют существующие реализации JSF, такие как Mojarra и MyFaces, и библиотеки компонентов JSF, такие как PrimeFaces и OmniFaces . Никто из них не использует библиотеки ресурсов таким образом. Они используют его (под одеялом, @ResourceDependency
или UIViewRoot#addComponentResource()
) следующим образом:
<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" />
Должно стать ясно, что оно в основном представляет общее имя библиотеки / модуля / темы, к которому обычно относятся все эти ресурсы.
Более простая идентификация
Таким образом, намного проще указать и различить, откуда эти ресурсы принадлежат и / или откуда. Представьте, что у вас есть primefaces.css
ресурс в вашем собственном веб-приложении, в котором вы переопределяете / настраиваете некоторые CSS по умолчанию PrimeFaces; если бы PrimeFaces не использовал имя библиотеки для собственного имени primefaces.css
, то собственное имя PrimeFaces не будет загружено, а вместо этого будет предоставлено веб-приложением, что нарушит внешний вид.
Кроме того, когда вы используете пользовательскую настройку ResourceHandler
, вы также можете применять более точный контроль над ресурсами, поступающими из определенной библиотеки, при library
правильном использовании. Если бы все библиотеки компонентов использовали бы «js» для всех своих файлов JS, как бы они ResourceHandler
отличались, если бы они исходили из библиотеки конкретных компонентов? Примерами являются OmniFaces CombinedResourceHandler
и GraphicResourceHandler
; проверьте createResource()
метод, в котором библиотека проверяется перед делегированием следующему обработчику ресурса в цепочке. Таким образом, они знают, когда создавать CombinedResource
или GraphicResource
для этой цели.
Следует отметить, что RichFaces сделал это неправильно. Он вообще не использовался library
и сам по себе создал еще один уровень обработки ресурсов, поэтому невозможно программно идентифицировать ресурсы RichFaces. Именно по этой причине OmniFaces CombinedResourceHander
пришлось ввести взлом на основе отражений , чтобы заставить его работать в любом случае с ресурсами RichFaces.
Ваш собственный веб-приложение
Ваше собственное веб-приложение не обязательно нуждается в библиотеке ресурсов. Вы бы лучше просто опустить это.
<h:outputStylesheet name="css/style.css" />
<h:outputScript name="js/script.js" />
<h:graphicImage name="img/logo.png" />
Или, если вам действительно нужно иметь его, вы можете просто дать ему более разумное общее имя, такое как «default» или название какой-либо компании.
<h:outputStylesheet library="default" name="css/style.css" />
<h:outputScript library="default" name="js/script.js" />
<h:graphicImage library="default" name="img/logo.png" />
Или, когда ресурсы относятся к какому-либо основному шаблону Facelets, вы также можете дать ему имя шаблона, чтобы было легче связывать друг друга. Другими словами, это больше для самодокументированных целей. Например, в /WEB-INF/templates/layout.xhtml
файле шаблона:
<h:outputStylesheet library="layout" name="css/style.css" />
<h:outputScript library="layout" name="js/script.js" />
И /WEB-INF/templates/admin.xhtml
файл шаблона:
<h:outputStylesheet library="admin" name="css/style.css" />
<h:outputScript library="admin" name="js/script.js" />
Для примера из реального мира, проверьте исходный код витрины OmniFaces .
Или, если вы хотите использовать одни и те же ресурсы в нескольких веб-приложениях и создали для этого «общий» проект, основанный на том же примере, что и в этом ответе, который, в свою очередь, встроен в веб-приложение в виде JAR /WEB-INF/lib
, то также укажите его как библиотеку. (имя свободно по вашему выбору; библиотеки компонентов, такие как OmniFaces и PrimeFaces, также работают таким образом):
<h:outputStylesheet library="common" name="css/style.css" />
<h:outputScript library="common" name="js/script.js" />
<h:graphicImage library="common" name="img/logo.png" />
Управление версиями библиотеки
Другое основное преимущество заключается в том, что вы можете правильно применять управление версиями библиотеки ресурсов к ресурсам, предоставляемым вашим собственным веб-приложением (это не работает для ресурсов, встроенных в JAR). Вы можете создать прямую дочернюю подпапку в папке библиотеки с именем в \d+(_\d+)*
шаблоне для обозначения версии библиотеки ресурсов.
WebContent
|-- resources
| `-- default
| `-- 1_0
| |-- css
| | `-- style.css
| |-- img
| | `-- logo.png
| `-- js
| `-- script.js
:
При использовании этой разметки:
<h:outputStylesheet library="default" name="css/style.css" />
<h:outputScript library="default" name="js/script.js" />
<h:graphicImage library="default" name="img/logo.png" />
Будет сгенерирован следующий HTML-код с версией библиотеки в качестве 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="" />
Итак, если вы отредактировали / обновили какой-либо ресурс, все, что вам нужно сделать, это скопировать или переименовать папку версии в новое значение. Если у вас есть несколько папок версий, JSF ResourceHandler
будет автоматически обслуживать ресурс с наибольшим номером версии в соответствии с числовыми правилами упорядочения.
Итак, при копировании / переименовании resources/default/1_0/*
папки в resources/default/1_1/*
подобное происходит:
WebContent
|-- resources
| `-- default
| |-- 1_0
| | :
| |
| `-- 1_1
| |-- css
| | `-- style.css
| |-- img
| | `-- logo.png
| `-- js
| `-- script.js
:
Тогда последний пример разметки сгенерирует следующий 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="" />
Это заставит веб-браузер запрашивать ресурс прямо с сервера, а не показывать ресурс с тем же именем из кэша, когда URL с измененным параметром запрашивается впервые. Таким образом, конечные пользователи не обязаны выполнять полное обновление (Ctrl + F5 и т. Д.), Когда им нужно получить обновленный ресурс CSS / JS.
Обратите внимание, что управление версиями библиотеки невозможно для ресурсов, включенных в файл JAR. Тебе нужен кастом ResourceHandler
. Смотрите также Как использовать управление версиями JSF для ресурсов в jar .
Смотрите также: