How to register a (Component)SystemEventListener for all UIInputs

后端 未结 1 1110
甜味超标
甜味超标 2021-01-06 00:41

I am trying to have a custom SystemEventListener that registers for all instances of type UIInput and reacts to their postValidate-Eve

相关标签:
1条回答
  • 2021-01-06 01:21

    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):

    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.

    ...

    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.
        }
    
    }
    

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

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

    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);
        }
    
        // ...
    }
    
    0 讨论(0)
提交回复
热议问题