jsfjsf-2phaselistener

How to implement a PhaseListener which runs at end of lifecycle?


How can I implement a PhaseListener which runs at end of the JSF lifecycle?


Solution

  • You need to implement the PhaseListener interface and hook on beforePhase() of the PhaseId_RENDER_RESPONSE. The render response is the last phase of the JSF lifecycle.

    public class MyPhaseListener implements PhaseListener {
    
        @Override
        public PhaseId getPhaseId() {
            return PhaseId.RENDER_RESPONSE;
        }
    
        @Override
        public void beforePhase(PhaseEvent event) {
            // Do your job here which should run right before the RENDER_RESPONSE.
        }
    
        @Override
        public void afterPhase(PhaseEvent event) {
            // Do your job here which should run right after the RENDER_RESPONSE.
        }
    
    }
    

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

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

    Update the above phase listener is indeed applicaiton-wide. To have a phase listener for a specific view, use the beforePhase and/or afterPhase attributes of the <f:view>.

    E.g.

    <f:view beforePhase="#{bean.beforePhase}">
        ...
    </f:view>
    

    with

    public void beforePhase(PhaseEvent event) {
        if (event.getPhaseId() == PhaseId.RENDER_RESPONSE) {
            // Do here your job which should run right before the RENDER_RESPONSE.
        }
    }
    

    A more JSF 2.0 way is by the way using the <f:event type="preRenderView">:

    <f:event type="preRenderView" listener="#{bean.preRenderView}" />
    

    with

    public void preRenderView() {
        // Do here your job which should run right before the RENDER_RESPONSE.
    }