JSFで'binding'属性はどのように機能するのですか?いつ、どのように使うべきですか?
質問
多くの資料がありますが
value
属性と
binding
属性を使用することができます。
私は両方のアプローチが互いにどのように異なるかに興味があります。与えられた。
public class User {
private String name;
private UICommand link;
// Getters and setters omitted.
}
<h:form>
<h:commandLink binding="#{user.link}" value="#{user.name}" />
</h:form>
を指定するとどうなるかは、非常にわかりやすいものです。
value
属性が指定されたときに起こることはとても簡単です。ゲッターが実行されて
name
属性の値を返すために実行されます。
User
ビーンに設定される。この値はHTML出力に出力される。
しかし、私はどのように
binding
がどのように機能するのか理解できませんでした。生成されたHTMLはどのようにして
link
プロパティの
User
ビーン?
以下は、手動で美化しコメントした後の生成された出力の関連する部分です (ただし、id
j_id_jsp_1847466274_1
が自動生成されたことと、2つの隠し入力ウィジェットがあることに注意してください)。
Sun の JSF RI、バージョン 1.2 を使用しています。
<form action="/TestJSF/main.jsf" enctype="application/x-www-form-urlencoded"
id="j_id_jsp_1847466274_1" method="post" name="j_id_jsp_1847466274_1">
<input name="j_id_jsp_1847466274_1" type="hidden" value="j_id_jsp_1847466274_1">
<a href="#" onclick="...">Name</a>
<input autocomplete="off" id="javax.faces.ViewState" name="javax.faces.ViewState"
type="hidden" value="-908991273579182886:-7278326187282654551">
</form>
はどこにあるかというと
binding
はここに格納されていますか?
どのように解決するのですか?
それはどのように動作しますか?
JSFビュー(Facelets/JSPファイル)がビルド/リストアされるとき、JSFコンポーネントツリーが生成されます。このとき
ビューのビルド時
で、すべての
binding
の属性が評価されます (
と共に
id
属性と、JSTL のようなタグハンドラによって
). JSF コンポーネントをコンポーネントツリーに追加する前に作成する必要がある場合、JSF は、コンポーネントツリーに追加される前に
binding
属性が事前に作成されたコンポーネントを返すかどうかを確認します(つまり、非
null
) を返し、もしそうなら、それを使います。もしそれが事前に作成されていないなら、JSFはコンポーネントを"通常の方法"で自動作成し、その後ろにあるセッターを呼び出します。
binding
属性の後ろのセッターを、自動生成されたコンポーネントインスタンスを引数として呼び出します。
効果としては、コンポーネントツリー内のコンポーネントインスタンスの参照をスコープ付き変数に束縛します。この情報は、コンポーネント自体の生成された HTML 表現では決して見えません。この情報は、いずれにせよ、生成される HTML 出力には全く関係ありません。フォームが送信され、ビューが復元されると、JSFコンポーネントツリーはゼロから再構築され、すべての
binding
属性は上の段落で説明したように再評価されます。コンポーネントツリーが再作成された後、JSFはJSFビューの状態をコンポーネントツリーにリストアします。
コンポーネントインスタンスはリクエストスコープされています!
知っておくべき重要なことは、具象コンポーネントインスタンスが効果的にリクエストスコープされていることです。それらはすべてのリクエストで新しく作成され、それらのプロパティはリストア ビュー フェーズ中に JSF ビュー ステートから値で満たされます。したがって、コンポーネントをバッキングビーンのプロパティにバインドする場合、バッキングビーンは は絶対に リクエストスコープより広い範囲にあるべきです。また JSF 2.0仕様書 の3.1.5章を参照してください。
3.1.5 コンポーネントバインディング
...
コンポーネントバインディングは,しばしば,マネージド・ビーン作成機能によって動的にインスタンス化されるJavaBeansと組み合わせて使用される( Bean作成機能(5.8.1項 「VariableResolverとデフォルトのVariableResolver」参照)を介して動的にインスタンス化されるJavaBeanと組み合わせて使用されることがよくあります。 アプリケーション開発者は アプリケーション開発者は、コンポーネントバインディング式によって指されるマネージドBeanを "request "スコープに置くことを強く推奨します。 "request "スコープに置くことを強くお勧めします。 これは、セッションまたはアプリケーションスコープに配置すると、スレッドセーフが必要になるためです。 UIComponentインスタンスは、単一のスレッドの内部で実行することに依存するからです。また セッション」スコープにコンポーネントバインディングを配置する場合、メモリ管理にも悪影響を及ぼす可能性があります。
そうでなければ、コンポーネントインスタンスは複数のリクエストで共有され、おそらく " 重複したコンポーネントID ビューで宣言されたバリデータ、コンバータ、およびリスナーは、以前のリクエストから既存のコンポーネント インスタンスに再接続されるため、エラーと奇妙な動作が発生します。症状は明確で、コンポーネントがバインドされているのと同じスコープ内の各リクエストで、複数回、さらに1回実行されるのです。
また、高負荷時 (つまり、複数の異なる HTTP リクエスト (スレッド) がまったく同じコンポーネントインスタンスに同時にアクセスし、操作する場合) には、遅かれ早かれ、たとえば以下のようなアプリケーションクラッシュに直面するかもしれません。
UIComponent.popComponentFromEL でスレッドがスタックしています。
または
JSF saveState() 中に HashMap の CPU 使用率が 100% でスレッドが停止する。
あるいは、いくつかの "strange"
IndexOutOfBoundsException
または
ConcurrentModificationException
は、JSF がビューの状態を保存したり復元したりするのに忙しく、JSF の実装ソースコードから直接やってくる (つまり、スタックトレースが示すように
saveState()
または
restoreState()
メソッドなど)を使用することができます。
また、一つのコンポーネントが基本的にコンポーネントツリー全体の残りの部分を参照するように
getParent()
と
getChildren()
を使用すると、単一のコンポーネントをビューまたはセッションスコープドBeanにバインドするときに、本質的にHTTPセッションで全体のJSFコンポーネントツリーを無駄に保存していることになります。これは、ビューに比較的多くのコンポーネントがある場合、利用可能なサーバー メモリの点で、本当にコストがかかります。
使用方法
binding
を使用することは悪い習慣です。
とはいえ
binding
をこのように使用し、コンポーネントインスタンス全体をBeanプロパティにバインドすることは、たとえリクエストスコープのBeanであっても、JSF 2.xではかなりまれな使用例であり、一般的にベストプラクティスではありません。これは、設計上の問題を示しています。通常、ビュー側でコンポーネントを宣言し、その実行時属性を
value
のような実行時属性、そしておそらく他の
styleClass
,
disabled
,
rendered
などを、通常のビーンプロパティに変換します。そして、コンポーネント全体を取得して属性に関連付けられたセッターメソッドを呼び出す代わりに、まさにそのビーンプロパティを操作するだけです。
静的なモデルに基づいてコンポーネントを動的に構築する必要がある場合、より良いのは
ビュービルドタイムタグを使用するのが良いでしょう。
を使用することです。
タグファイル
の代わりに
createComponent()
,
new SomeComponent()
,
getChildren().add()
といった具合です。また
どのように古いJSPのスニペットをJSFの同等物にリファクタリングしますか?
あるいは、動的なモデルに基づいてコンポーネントを動的にレンダリングする必要がある場合、単に
イテレータコンポーネント
(
<ui:repeat>
,
<h:dataTable>
など)。参照
JSFコンポーネントを動的に追加する方法
.
コンポジットコンポーネントは全く別の話です。コンポーネントを
<cc:implementation>
内のコンポーネントをバッキングコンポーネント(つまり
<cc:interface componentType>
. a.o. も参照してください。
java.util.Dateをf:convertDateTimeを用いて時間と分を表す二つのh:inputTextフィールド上に分割します。
と
JSF 2.0コンポジットコンポーネントで動的リストを実装する方法は?
使用するのは
binding
ローカルスコープで
しかし、時には特定のコンポーネントの内部から別のコンポーネントの状態を知りたいことがあります。アクション/値に依存する検証に関する使用例では、より頻繁にあります。そのために
binding
属性が使えますが
ではなく
はビーンプロパティと組み合わせて使うことができます。ローカルELスコープで一意な変数名を指定するだけなら
binding
属性で指定します。
binding="#{foo}"
で、コンポーネントはレンダーレスポンス中に同じビューの他の場所で直接
UIComponent
で参照可能な
#{foo}
. このような解決策が答えに使われているいくつかの関連した質問を紹介します。
-
JSFのコンポジットコンポーネントにコンポーネントIDを渡すためにEL式を使用します。
(それも先月から...)
こちらもご覧ください。
関連
-
[解決済み] JSF 2.2でターゲットが到達できない、識別子がヌルに解決される [重複] 。
-
[解決済み] javax.validation.ConstraintViolationException
-
[解決済み] p:dashboardが終了してもソート順を維持する。
-
[解決済み】JSF、Servlet、JSPの違いは何ですか?
-
[解決済み】JSFリソースライブラリは何のためにあり、どのように使用すべきですか?
-
[解決済み】JSF 2.0 Faceletsを使用してXHTMLに別のXHTMLを含めるにはどうすればよいですか?
-
[解決済み] h:commandLinkの代わりにh:outputLinkを使うべきですか?
-
[解決済み] dataTableやui:repeatのコマンドリンクに選択した行を渡すにはどうしたらいいですか?
-
[解決済み] JSFのページで、改行されないスペース文字を挿入するには?
-
[解決済み] FaceletsのEL boolean式で&&を使うには?
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] java.lang.ClassNotFoundException: javax.faces.webapp.FacesServlet
-
[解決済み] javax.validation.ConstraintViolationException
-
[解決済み] actionとactionListenerの違い
-
[解決済み] javax.el.PropertyNotFoundException の識別と解決。ターゲットに到達できない
-
[解決済み] divタグをレンダリングできるjsfコンポーネントは何ですか?
-
[解決済み] h:commandLinkの代わりにh:outputLinkを使うべきですか?
-
[解決済み] PrimeFaces p:fileUploadを使うには?リスナーメソッドが呼び出されない、またはUploadedFileがNullである / エラーが発生する / 使えない
-
[解決済み] サーブレット関連クラスでJSFマネージドBeanを名前付きで取得する
-
[解決済み] JSFでEL empty演算子はどのように動作しますか?
-
[解決済み] FaceletsのEL boolean式で&&を使うには?