28

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

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Mahmoud Saleh
  • 33,303
  • 119
  • 337
  • 498

2 Answers2

44

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.
}
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • 1
    This is not related to the topic in anyway. In `event.getPhaseId() == PhaseId.RENDER_RESPONSE` is `==` okay instead of `equals`? – Bhesh Gurung Dec 05 '11 at 18:45
  • 1
    @gurung: read `PhaseId` javadoc: http://docs.oracle.com/javaee/6/api/javax/faces/event/PhaseId.html It's a typesafe constant. In any way, it has no `equals()` overriden and thus inherits `Object#equals()` which does in turn basically already `==`. – BalusC Dec 05 '11 at 18:54
  • That's what I was expecting. I wanted make sure because I have been using `equals` blindly. Thanks for the explanation. – Bhesh Gurung Dec 05 '11 at 19:01
  • @BalusC what if i want to make something after rendering the view not pre rendering, is there's an equivalent phase, or it's done in another way ? – Mahmoud Saleh Dec 05 '11 at 23:01
  • 1
    Do the job in `afterPhase()` method or use ``. – BalusC Dec 05 '11 at 23:25
  • and the after phase method should be as follows : `public void afterPhase(PhaseEvent event) { if (event.getPhaseId() == PhaseId.RENDER_RESPONSE) { } }` or without the if condition ? – Mahmoud Saleh Dec 05 '11 at 23:30
  • With, of course. The same as in my answer. It will be invoked on every phase the current request is running through. – BalusC Dec 05 '11 at 23:33
  • @BalusC what is annotation of `` ? i dont want to write it in `xml` file – Mohsin AR Feb 17 '14 at 18:08
5

In jsf 2 you can use <f:phaseListener type="my.MyPhaseListener"> to hook MyPhaseListener for some facelet. MyPhaseListener should implement PhaseListener and override

  • afterPhase - with code to be run after end of phase
  • beforePhase - with code to be run before phase started
  • getPhaseId - PhaseId enum specifying name of phase for which the listener to be invoked (PhaseId.RENDER_RESPONSE as last phase of lifecycle)