5

我正在尝试有一个SystemEventListener注册所有类型实例UIInput并对其postValidate-Events做出反应的自定义。根据我在网上找到的一个示例,我设法通过以下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源类。都没有奏效。

2)我试过

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

它既不适用于 UIInput 也不适用于 html.HtmlInputText。

现在,当我为所有其他类型的 HTML 输入复制相同的 XML 配置时,这可以解决问题,但它只会使 xml 变得混乱,而且对我来说似乎很烦人。

所以问题是:我通常对 @ListenerFor 注释做错了吗?对哪些源类可能存在限制,即为什么我不能使用更通用的 UIInput?有没有比重复 XML 更有效的方法来为所有这些不同的输入注册侦听器?最后:我宁愿实施ComponentSystemEventListener. 假设上述问题已解决,我只需更改implements-Statement 并processEvent相应地实现摘要,对吗?在这种情况下,这会一样工作还是registration/xml-config不同(例如,可能<component-system-event-listener>不仅仅是<system-event-listener>

(并且作为事后说明:只是我,还是很难在网络上找到此类东西的任何重要示例?)

4

1 回答 1

3

@ListenerFor应该在UIComponentor实现上设置,而Renderer不是在独立SystemEventListener实现上设置。另见javadoc(重点是我的):

默认实现必须支持将此注释附加到UIComponentRenderer类。在这两种情况下,此处描述的注释处理必须在 的任何变体的实现期间开始,Application.createComponent()并且必须在UIComponent实例从createComponent(). 注释处理必须根据语义上等效于以下的算法进行。

...

为了拥有一个全局侦听器,而不是特定于UIComponentor Renderer,最好的办法是创建和注册一个PhaseListener将侦听器订阅到视图根的 a 。

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 回答