Search code examples
ajaxjsfjsf-2initializerpostconstruct

JSF2 preRenderComponent is called always when f:ajax is executed


I have an JSF page backed by NewsBean.java which has <f:event type="preRenderComponent" listener="#{newsBean.init}" /> as bean initializer.

There is a button at the bottom of the page for sending comments which has: <f:ajax event="click" execute="@form" render="@form" listener="#{newsBean.sendComment}" /> and is surrounded by an <h:form>. When button is clicked, NewsBean.init() is always called.

My bean scope is view. Is this a valid behavior (calling always init())? How can I prevent always calling init()?


Solution

  • A preRender listener is always invoked on pre render event, regardless of if it's an initial request or a postback request. Every single request has a render response phase, regardless of if it's a normal request or ajax request. So this behaviour is by specification. You need to check yourself in the listener method if it's a postback request or not by checking FacesContext#isPostback().

    public void sendComment() {
        if (!FacesContext.getCurrentInstance().isPostback()) {
            // ...
        }
    }
    

    The <f:event type="preRenderXxx"> (where Xxx can be View or Component) is by the way in essence a "workaround approach" for the functional requirement of being able to invoke a bean action method after the view parameters are been processed on the initial request. In the upcoming JSF 2.2 a new <f:viewAction> tag will be introduced which should do exactly the job as intented:

    <f:viewAction action="#{newsBean.sendComment}" />
    

    This tag supports an onPostback attribute which already defaults to false:

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

    JSF 2.2 will be released the first quart of 2012. Snapshot releases of JSF 2.2 are currently already available.