1. ホーム
  2. jsf

[解決済み】JSFリソースライブラリは何のためにあり、どのように使用すべきですか?

2022-04-04 13:57:07

質問

JSFについて <h:outputStylesheet> , <h:outputScript> そして <h:graphicImage> コンポーネントには library 属性があります。これは何でしょうか、どのように使うべきでしょうか。ウェブ上には、一般的なコンテンツ/ファイル・タイプで次のように使用する例がたくさんあります。 css , jsimg (または 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の出力も少し変わっています。のコンテキストパスが与えられると /contextnameFacesServlet の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&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が初めてリクエストされたとき、ウェブブラウザはキャッシュから同じ名前のリソースを表示する代わりに、サーバーから直接リソースをリクエストするように強制されます。こうすることで、エンドユーザーが更新された CSS/JS リソースを取得する必要があるときに、ハードリフレッシュ (Ctrl+F5 など) を実行する必要がありません。

ライブラリのバージョン管理は、JARファイルに含まれるリソースでは不可能であることに注意してください。その場合は、カスタム ResourceHandler . 以下もご参照ください。 JSFのバージョン管理をjarのリソースに利用する方法 .

こちらもご覧ください。