如何注册为所有UIInputs一个(组件)SystemEventListener [英] How to register a (Component)SystemEventListener for all UIInputs

查看:248
本文介绍了如何注册为所有UIInputs一个(组件)SystemEventListener的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想有一个自定义的 SystemEventListener 即注册了 UIInput 类型的所有实例并响应他们的 postValidate -Events。根据一个例子,我在网上找到我设法在 faces-config.xml中注册它的HtmlInputText 一个运行$ C>如下:

I am trying to have a custom SystemEventListener that registers for all instances of type UIInput and reacts to their postValidate-Events. Based on an example I found on the web I managed to get one running for HtmlInputText by registering it in the faces-config.xml as follows:

<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)拓宽这对于一般和2 UIInputs)工作使用 @ListenerFor 标注,但我似乎无法得到任何它的工作。

I then tried to 1) broaden this to work for UIInputs in general and to 2) use the @ListenerForannotation, but I just can't seem to get either of it to work.

1)我真的无法找到任何实例或文件,所以我只是一个试图左右)使用定义多源类的标签或B) javax.faces.component.UIInput 源级。但是都没有成功。

for 1) I couldn't really find any examples or documentation, so i just tried around by a) defining multiple source-class-tags or by b) using javax.faces.component.UIInput as source-class. Neither worked.

2)我试图

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

该工作既不UIInput也不是html.HtmlInputText。

which worked neither for UIInput nor for html.HtmlInputText.

现在,当我复制了所有其他类型的HTML输入相同的XML配置,这样做的伎俩,但它只是杂波了XML和共似乎很讨厌我。

Now, when I duplicate the same XML-configuration for all the other types of HTML-Inputs, this does the trick, but it just clutters up the xml and altogether seems quite annoying to me.

所以,问题是:难道我通常做一些错误的注释@ListenerFor?是否有限制上源类是可能的,即我为什么不能用更通用的UIInput?有没有注册侦听器不是重复的XML所有这些不同的输入,更有效的方法?最后:我宁愿要落实 ComponentSystemEventListener 。假设上述问题得到解决,我只是修改工具语句来贯彻的processEvent 相应的抽象,对?将这项工作完全一样或登记/ XML的配置在这种情况下,不同的(例如,也许&lt;成分,系统事件侦听器&GT; ,而不是仅仅&lt;系统事件侦听&GT;

So the question is: Am I generally doing something wrong with the @ListenerFor annotation? Is there a restriction on which source-classes are possible, i.e. why can't I use the more generic UIInput? Is there a more efficient way to register the listener for all those different inputs than repeating the XML? And finally: I'd rather like to implement ComponentSystemEventListener. Assuming that the above problem was resolved, I'd just change the implements-Statement and implement the abstract processEvent accordingly, right? Would that work just the same or is the registration/xml-config different in this case (e.g. maybe <component-system-event-listener> instead of just <system-event-listener>?

(并作为后注:只有我或者是一种很难找到这种东西在网络上的任何非平凡的例子)

(and as an after-note: is it just me or is it kind of hard to find any non-trivial examples for this kind of stuff on the web?)

推荐答案

@ListenerFor 应该是在设置 UIComponent 渲染的实施,而不是一个独立的 SystemEventListener 的实施。又见的javadoc (重点煤矿):

The @ListenerFor is supposed to be set on an UIComponent or Renderer implementation, not on a standalone SystemEventListener implementation. See also the javadoc (emphasis mine):

默认的实现必须支持此注释附加到 UIComponent 渲染类。在这两种情况下,本文描述的注释处理必须的任何变体的实施过程中展开 Application.createComponent()和之前的 UIComponent 实例从 createComponent()返回。注释处理必须根据算法语义上等同于执行下述操作。

The default implementation must support attaching this annotation to UIComponent or Renderer classes. In both cases, the annotation processing described herein must commence during the implementation of any variant of Application.createComponent() and must complete before the UIComponent instance is returned from createComponent(). The annotation processing must proceed according to an algorithm semantically equivalent to the following.

...

为了有一个全球性的听众,而不是特定于 UIComponent 渲染,最好的办法是创造并注册一个的PhaseListener 这赞同听者视图根。

In order to have a global listener, not specific to an UIComponent or Renderer, your best bet is creating and registering a PhaseListener which subscribes the listener to the view root.

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中如下:

To get it to run, register it as follows in faces-config.xml:

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

您甚至可以让你的 InputPostValidationListener 本身就是一个的PhaseListener

You can even make your InputPostValidationListener itself a PhaseListener.

public class InputPostValidationListener implements PhaseListener, SystemEventListener {

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

    // ...
}

这篇关于如何注册为所有UIInputs一个(组件)SystemEventListener的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆