Search code examples
jsf-2phaselistener

How to apply a JSF2 phaselistener after viewroot gets built?


In my JSF2 application I have a phaselistener that needs to be executed before RENDER_RESPONSE but after JSF has built the viewroot.

First, what I did is register my PhaseListener in faces-config. The listener then gets called, but when I perform the beforePhase, getViewRoot().getChildren() is still empty.

Secondly, I found how to do this by adding the following on my xhtml pages:

<f:phaseListener type="be.application.PolicyController" />

This works fine, but adding this to each of my pages would be extremely tedious. Hence I'm looking for a possibility to do this once for my application.

Any ideas how this can be done?


Solution

  • Register a system event listener for the PreRenderViewEvent in faces-config:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <faces-config xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
        version="2.0">
    
        <application>
            <system-event-listener>
                <system-event-listener-class>test.PreRenderViewListener</system-event-listener-class>
                <system-event-class>javax.faces.event.PreRenderViewEvent</system-event-class>
            </system-event-listener>
        </application>
    
    </faces-config>
    

    Example of a listener:

    public class PreRenderViewListener implements SystemEventListener {
    
        @Override
        public void processEvent(SystemEvent event) throws AbortProcessingException {
            UIViewRoot root = (UIViewRoot) event.getSource();
            System.out.println(root.getChildCount());
        }
    
        @Override
        public boolean isListenerForSource(Object source) {
            return true;
        }
    
    }