6

この質問で説明されているように、バッキング Bean 側のフォームでいくつかのフィールド検証を実行しようとしています。このために、違反しているフィールドにアクセスしてマークを付けたいと思います。Web を検索すると、これを行うには 2 つの方法があるようです。

  • コンポーネントをアクセス用にバッキング Bean に格納し、binding属性を介して JSF ページで使用します。
  • JSF ページで標準の値バインディングを使用し、Bean からコンポーネントにアクセスする必要がある場合は、UIViewRoot.findComponent(String id)

私が見る限り、どちらの方法にも欠点があります。コンポーネント バインディングはバッキング Bean を変数とゲッター/セッターで爆破します。一部のサイトでは、コンポーネント バインディングの使用をまったく推奨していません。いずれにせよ、リクエストスコープが推奨されます。一方、 findComponent() は常にツリーをトラバースしますが、コストがかかる場合とそうでない場合がありますよね? (さらに、現時点ではコンポーネントがまったく見つかりませんが、それは別の問題です)

どちらに行くべきですか?これらは交換可能な代替案ですか?そうでない場合は、どのような基準に基づいて選択しますか? 現在、適切な決定を下すのに十分な洞察力がありません...

4

1 に答える 1

9

まず第一に、選択に関係なく、どちらも悪い習慣です。「バインディング」属性は JSF でどのように機能しますか?も参照してください。いつ、どのように使用する必要がありますか?

どちらかを選択する必要がある場合は、コンポーネント バインディングの方が確実に高速で安価です。UIComponent#findComponent()によって行われるツリースキャンがパフォーマンスに影響を与えることは、論理的に完全に理にかなっています。

実際、コンポーネント バインディングを保持するバッキング Bean はリクエスト スコープにする必要がありますが、ビジネス ロジックを保持する別のスコープ バッキング Bean を簡単に挿入できます@ManagedProperty

よりクリーンなアプローチはMap、すべてのコンポーネント バインディングの as holder を使用することです。次のエントリを に追加するだけですfaces-config.xml

<managed-bean>
    <managed-bean-name>components</managed-bean-name>
    <managed-bean-class>java.util.HashMap</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
</managed-bean>

これは次のように使用できます

<h:inputSome binding="#{components.input1}" />
<h:inputSome binding="#{components.input2}" />
<h:inputSome binding="#{components.input3}" />

そして、これは他の Bean で次のように取得できます。

Map<String, UIComponent> components = (Map<String, UIComponent>) externalContext.getRequestMap().get("components");

このように、個々のプロパティ/ゲッター/セッターの指定について心配する必要はありません。上記の例では、 には 、 、 のMapキーを持つ 3 つのエントリが含まれinput1input2それぞれinput3UIComponentインスタンスが値として含まれます。


具体的な質問とは関係ありませんが、アクションメソッドで検証を実行するよりも、他の質問で説明したように、具体的な問題に対するはるかに簡単な解決策があるかもしれません(実際には悪い設計です)。私はそこに答えを投稿しました。

于 2012-09-18T12:51:20.517 に答える