Для чого використовується бібліотека ресурсів JSF та як її використовувати?


228

JSF <h:outputStylesheet>, <h:outputScript>і <h:graphicImage>компоненти мають libraryатрибут. Що це таке і як це слід використовувати? Є багато прикладів в Інтернеті , які використовують його як слід зі звичайним типом контенту / файлів css, jsі img(або image) в якості імені бібліотеки в залежності від використовуваного тега:

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

Чим це корисно? libraryЗначення в цих прикладах , як видається, просто повторюючи те , що вже було представлено ім'ям тега. Для цього <h:outputStylesheet>він заснований на назві тегу, що вже очевидно, що він являє собою "бібліотеку CSS". Яка різниця у наступному, який також просто працює так само?

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

Крім того, згенерований HTML вихід трохи відрізняється. З огляду на контекстний шлях /contextnameта FacesServletвідображення на шаблоні URL-адреси *.xhtml, перший генерує наступний HTML із назвою бібліотеки як параметр запиту:

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

Хоча останній генерує наступний HTML із назвою бібліотеки просто на шляху 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="" />

Останній підхід має задній погляд також більше сенсу, ніж колишній підхід. Наскільки саме libraryтоді атрибут корисний?

Відповіді:


256

Насправді всі ці приклади в Інтернеті, де загальний вміст / тип файлу, такі як "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 не завантажуватиметься, а замість цього постачається webapp, що порушить зовнішній вигляд.

Крім того, коли ви користуєтеся користувачем 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" />

Або, якщо вам дійсно потрібно мати його, ви можете просто дати йому більш розумне загальне ім’я, наприклад, "за замовчуванням" або якусь назву компанії.

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

Отже, якщо ви відредагували / оновили якийсь ресурс, то все, що вам потрібно зробити, це скопіювати або перейменувати папку версій у нове значення. Якщо у вас є кілька папок версій, то 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&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="" />

Це змусить веб-браузера запитувати ресурс прямо з сервера, а не показувати той самий ім'я з кеша, коли вперше запитується URL із зміненим параметром. Таким чином, не вимагається оновлення оновлень (Ctrl + F5 і так далі), коли їм потрібно отримати оновлений ресурс CSS / JS.

Зауважте, що версія бібліотеки неможлива для ресурсів, укладених у файл JAR. Вам потрібен звичай ResourceHandler. Див. Також Як використовувати версію JSF для ресурсів у банку .

Дивитися також:


2
Чи можна використовувати EL для бібліотеки? Тож, якщо я хотів мати ресурси / за замовчуванням та ресурси / почуттяFroggyToday, я можу зробити щось на зразок бібліотека = "# {someLibraryHere}", щоб передати карту someLibraryHere у вибрану вами бібліотеку, і не потрібно кожного разу покладатися на перейменування каталогу ресурсів у вищу версію Я хотів їх змінити.
gebuh

Коли ви скажете, що бібліотека = адміністратор або бібліотека = макет, чи є ці папки (адміністратор і макет) у папці ресурсів?
Корай Тугай

Ум. Дуже цікавий Балюс. Я стикаюся з проблемою у веб-додатку, де файл теми.css залишається порожнім при завантаженні. Це трапляється лише після різних повторних розробок (у JBOSS EAP). URL-адреса css виглядає так: /javax.faces.resource/css/theme.css.xhtml?ln=default&v=3_3_0_130416, і це оголошено так: <h: outputStylesheet library = "default" name = "css / topic. css "target =" head "/>. Можливо, це питання пов’язане з проблемами версій?
Рікардо Віла

2
Чи libraryзмінилися дозволені символи для значення або щось, що пов'язане з ним, між моєю мірою 2.2.5 (2.2.5-jbossorg-3, wildfly 8.0) та 2.2.11 (2.2.11-jbossorg-1)? Я не можу знайти щось у випуску. Див stackoverflow.com/questions/35719808 / ...
Kukeltje

3
Дякую @BalusC. На жаль, навіть власний навчальний посібник Java EE 7 Oracle дає неправильний приклад, використовуючи ім’я бібліотеки cssу розділі 8.6 Веб-ресурси та робить це неправильно з css та зображеннями в прикладі програми "Знайти номер-jsf" .
Jesper
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.