[解決済み】JSFリソースライブラリは何のためにあり、どのように使用すべきですか?
質問
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="" />
一方、後者はURIのパスにライブラリ名を入れただけの以下のようなHTMLを生成します。
<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
属性は有用でしょうか?
どのように解決するのですか?
実は、Web上で、"js", "css", "img" などの共通のコンテンツ/ファイルタイプがライブラリ名として使われている例は、すべて以下の通りです。 誤解を招く .
実際の事例
まず始めに、既存のJSFの実装である
モジャラ
と
マイフェイス
のようなJSFコンポーネント・ライブラリと
プライムファイス
と
オムニフェーズ
を使用しています。リソースライブラリをこのように使っているものはありません。彼らはそれを(隠蔽して
@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
リソースで、PrimeFacesのデフォルトCSSをオーバーライド/微調整しています。
primefaces.css
その場合、PrimeFaces自身のものはロードされず、代わりにウェブアプリが提供するものがロードされ、ルックアンドフィールを壊してしまうでしょう。
また、カスタム
ResourceHandler
の場合、特定のライブラリから来るリソースをより細かく制御することもできます。
library
を正しい方法で使用します。もし、すべてのコンポーネント・ライブラリが、すべてのJSファイルに "js"を使っていたら、どのようにして
ResourceHandler
特定のコンポーネント・ライブラリからのものであるかどうかを区別することはできないのでしょうか?例としては、OmniFaces
CombinedResourceHandler
と
GraphicResourceHandler
をチェックします。
createResource()
メソッドで、次のリソースハンドラに委譲する前にライブラリがチェックされます。こうすることで、彼らはいつ
CombinedResource
または
GraphicResource
を使用します。
注目すべきは、RichFacesが間違ったことをしたことです。それはどんな
library
そのため、RichFacesのリソースをプログラム的に識別することは不可能です。それはまさに
オムニフェーズ
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ショーケースのソースコード .
また、複数のウェブアプリで同じリソースを共有したい場合、先ほどと同じ例をもとに、quot;common" プロジェクトを作成します。
この回答
これは、JARとしてWebアプリケーションの
/WEB-INF/lib
そして、それをライブラリとして参照することもできます(名前は自由に決めてください。)
<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が初めてリクエストされたとき、ウェブブラウザはキャッシュから同じ名前のリソースを表示する代わりに、サーバーから直接リソースをリクエストするように強制されます。こうすることで、エンドユーザーが更新された CSS/JS リソースを取得する必要があるときに、ハードリフレッシュ (Ctrl+F5 など) を実行する必要がありません。
ライブラリのバージョン管理は、JARファイルに含まれるリソースでは不可能であることに注意してください。その場合は、カスタム
ResourceHandler
. 以下もご参照ください。
JSFのバージョン管理をjarのリソースに利用する方法
.
こちらもご覧ください。
- JSFリソースのバージョン管理
- JSF2 静的リソースキャッシング
- 複数のJSFプロジェクトでコードを共有するための構造体
- JSF2.0仕様 - 第2.6章 リソース処理
関連
-
[解決済み] javax.faces.application.ViewExpiredException: ビューを復元できませんでした
-
[解決済み] JSF 2.2でターゲットが到達できない、識別子がヌルに解決される [重複] 。
-
[解決済み] javax.validation.ConstraintViolationException
-
[解決済み] actionとactionListenerの違い
-
[解決済み】JSF、Servlet、JSPの違いは何ですか?
-
[解決済み】JSFリソースライブラリは何のためにあり、どのように使用すべきですか?
-
[解決済み】JSF 2.0 Faceletsを使用してXHTMLに別のXHTMLを含めるにはどうすればよいですか?
-
[解決済み] <f:metadata>、<f:viewParam>、<f:viewAction>は何に使えるのでしょうか?
-
[解決済み] javax.el.PropertyNotFoundException の識別と解決。ターゲットに到達できない
-
[解決済み] divタグをレンダリングできるjsfコンポーネントは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] javax.faces.application.ViewExpiredException: ビューを復元できませんでした
-
[解決済み] <f:facet>は何をするもので、どのような場合に使用するのですか?
-
[解決済み] java.lang.ClassNotFoundException: javax.faces.webapp.FacesServlet
-
[解決済み] java.lang.ClassNotFoundException: javax.servlet.jsp.jstl.core.Config [duplicate].
-
[解決済み] actionとactionListenerの違い
-
[解決済み】JSF 2.0 Faceletsを使用してXHTMLに別のXHTMLを含めるにはどうすればよいですか?
-
[解決済み】PrimeFacesのprocess/updateとJSFのf:ajax execute/renderの属性を理解する。
-
[解決済み] JSF2 FaceletsでJSTL...意味があるのか?
-
[解決済み] javax.el.PropertyNotFoundException の識別と解決。ターゲットに到達できない
-
[解決済み] h:commandLinkの代わりにh:outputLinkを使うべきですか?