5

SystemEventListenerタイプのすべてのインスタンスを登録し、それらの-EventsUIInputに反応するカスタムを作成しようとしています。postValidateWeb で見つけた例に基づいて、次HtmlInputTextのように登録することで実行することができました。faces-config.xml

<system-event-listener>
   <source-class>javax.faces.component.html.HtmlInputText</source-class>
   <system-event-class>javax.faces.event.PostValidateEvent</system-event-class>
   <system-event-listener-class>com.ourcompany.ourproduct.validators.inputPostValidationListener</system-event-listener-class>
 </system-event-listener>

次に、1)これを拡張して、一般にUIInputsで機能するようにし、2)@ListenerFor注釈を使用しようとしましたが、どちらも機能しないようです。

1)例やドキュメントが実際に見つからなかったので、a)複数のソースクラスタグを定義するか、b)javax.faces.component.UIInputソースクラスとして使用して試してみました。どちらも機能しませんでした。

for 2) やってみました

@ListenerFor(systemEventClass = PostValidateEvent.class, sourceClass = UIInput.class)

UIInput でも html.HtmlInputText でも機能しませんでした。

ここで、他のすべてのタイプの HTML 入力に対して同じ XML 構成を複製すると、これでうまくいきますが、xml が乱雑になるだけで、全体として非常に面倒に思えます。

質問は、一般的に @ListenerFor アノテーションで何か間違ったことをしているのですか? 可能なソースクラスに制限はありますか?つまり、より一般的な UIInput を使用できないのはなぜですか? XML を繰り返すよりも、これらすべての異なる入力に対してリスナーを登録する効率的な方法はありますか? そして最後に、私は実装したいと思いますComponentSystemEventListener。上記の問題が解決されたと仮定すると、ステートメントを変更して、それに応じimplementsて抽象を実装するだけprocessEventですよね? それはまったく同じように機能しますか、またはこの場合、登録/xml-configが異なります(たとえば<component-system-event-listener>、単に<system-event-listener>?

(そして、補足として: それは私だけですか? それとも、この種のものの自明でない例をウェブ上で見つけるのはちょっと難しいですか?)

4

1 に答える 1

3

は、スタンドアロンの実装ではなく、 orの実装で@ListenerFor設定する必要があります。javadocも参照してください(強調鉱山):UIComponentRendererSystemEventListener

UIComponentデフォルトの実装は、この注釈をまたはRendererクラスに添付することをサポートする必要があります。どちらの場合も、ここで説明する注釈処理は、 のバリアントの実装中に開始し、からインスタンスが返されるApplication.createComponent()前に完了する必要があります。注釈処理は、以下と意味的に等価なアルゴリズムに従って進めなければなりません。UIComponentcreateComponent()

...

UIComponentまたはに固有ではないグローバル リスナーを使用するには、リスナーをビュー ルートにサブスクライブする をRenderer作成して登録することをお勧めします。PhaseListener

public class PostValidateListener implements PhaseListener {

    @Override
    public PhaseId getPhaseId() {
        return PhaseId.PROCESS_VALIDATIONS;
    }

    @Override
    public void beforePhase(PhaseEvent event) {
        event.getFacesContext().getViewRoot()
            .subscribeToViewEvent(PostValidateEvent.class, new InputPostValidationListener()); // Capitalize class name?
    }

    @Override
    public void afterPhase(PhaseEvent event) {
        // NOOP.
    }

}

実行するには、faces-config.xml で次のように登録します。

<lifecycle>
    <phase-listener>com.example.PostValidateListener</phase-listener>
</lifecycle>

InputPostValidationListener自分自身を にすることもできますPhaseListener

public class InputPostValidationListener implements PhaseListener, SystemEventListener {

    @Override
    public void beforePhase(PhaseEvent event) {
        event.getFacesContext().getViewRoot().subscribeToViewEvent(PostValidateEvent.class, this);
    }

    // ...
}
于 2012-12-06T16:48:06.423 に答える