Ravi Kadaboina
Ravi Kadaboina

Reputation: 8574

Phase listener to listen only if not a postback

Basically, I need to call a method after RENDER_RESPONSE phase. I tried this:

<f:phaseListener type="com.examples.MyPhaseListener"/>

The above listener is listenening all the time even for ajax calls. I tried

rendered="#{!facesContext.postback}" 

but its not applicable here I guess. So I tried this as mentioned in this post Is it possible to disable f:event type="preRenderView" listener on postback?:

public void beforePhase(PhaseEvent pe) {
 if (!FacesContext.getCurrentInstance().isPostback()) {
          //do nothing
      }
}

public void afterPhase(PhaseEvent pe) {
      if (!FacesContext.getCurrentInstance().isPostback()) {
           if (pe.getPhaseId() == PhaseId.RENDER_RESPONSE) {
               //call a method
            }
      }
}

It is working but is there any other way to disable the listener after the initial response? I also tried preRenderComponent but it is called in before RENDER_RESPONSE phase and it looks like it is not rendering response until the method is out of the stack ( basically it is not asynchronous). So I feel there is not much advantage of SystemEvents like preRenderView and preRenderComponent when compared to calling them in PostConstruct.

Upvotes: 3

Views: 3127

Answers (1)

BalusC
BalusC

Reputation: 1109570

There's not really another way to achieve the functional requirement. A Filter wherein you do the job after the chain.doFilter(request, response) call should also work, but this doesn't give you access to the faces context (although a lot of JSF specific data is also available by the standard Servlet API).

As to your phase listener, if you need to get it to listen on render response only, then add

public PhaseId getPhaseId() {
    return PhaseId.RENDER_RESPONSE;
}

This way you don't need to check the current phase in the listener methods.

public void afterPhase(PhaseEvent event) {
    if (!FacesContext.getCurrentInstance().isPostback()) {
        // ...
   }
}

In the upcoming JSF 2.2 there will by the way be a new tag which understands isPostback(), the <f:viewAction>:

<f:viewAction action="#{bean.action}" onPostback="false" />

However, it runs during invoke action phase only.

Upvotes: 3

Related Questions