1

In my web app, JSF2 (mojarra 2.1.20), there is a strange behaviour on a page having a component with the following snippet:

<h:commandLink ... action="#{cc.attrs.bean.next}">
    <f:ajax execute="@this" render=":#{cc.clientId}" />
</h:commandLink>

The action next() is not always called. I've found out that the problem is related for some reason to the url parameter id:

<f:metadata>
    <f:viewParam name="id" value="#{torneoBean.idParam}" required="true" />
</f:metadata>

When I insert the viewParam above the problem occurs. But I cannot get rid of it. Debugging ajax request it seems that start, success, complete event sequence is called (no errors), the components to render are correctly rendered but the action is not fired. Is there a way to debug this situation and find out what is the root cause of the problem?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
maxqua72
  • 391
  • 1
  • 9
  • 25

1 Answers1

3

Apparently you haven't attached a <h:message(s)> to the <f:viewParam id="torneo_id"> and/or you aren't updating it on every ajax request. You would otherwise have seen a required validation error on it. The concrete problem is essentially covered by point 3 of commandButton/commandLink/ajax action/listener method not invoked or input value not updated.

As to the cause, the <f:viewParam> is executed on every single HTTP request, also on ajax postbacks. When the ajax request is sent, the desired request parameter is not present anymore in the current request and hence <f:viewParam> fails the required validation.

There are several solutions to this:

  1. Retain the request parameter for the subsequent request by <f:param> in the command component.

    <h:commandLink ...>
        ...
        <f:param name="id" value="#{param.id}" />
    </h:commandLink>
    
  2. Make it required during a non-postback only. This works only if the page is initially opened by a GET request. If it's however opened by a non-redirect navigation, then it would still fail.

    <f:viewParam ... required="#{not facesContext.postback}" />
    
  3. Replace <f:viewParam> by the one provided by JSF utility library OmniFaces, the <o:viewParam>. It implicitly turns off required="true" on postbacks so that you kan keep using the same attributes.

    <o:viewParam ... required="true" />
    
Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks BalusC! The solution #2 solves my problem, but in general how can I debug problems like this one? h:message surely could help but could I have used a phase listener to catch this issue (a sort of mis-behaviour detector) and all other issues related to actions not called? – maxqua72 Apr 07 '13 at 06:16
  • A phase listener which logs the current phase would indeed have hinted that update model values and invoke application phases are been skipped. Further, haven't you noticed that queued but undisplayed messages are been logged by JSF? At least, Mojarra does that. As last resort, well, putting a breakpoint in `FacesServlet#service()` and advancing form there should also give a lot of insight. The more so you do, the better you understand the JSF lifecycle and the easier you can spot potential issues. – BalusC Apr 07 '13 at 11:31
  • It was strange no errors or warning were traced in the log about the queued and undisplayed messages. Log was clean, that's why I asked a way to debug. It will be definetly helpful for circumstances like this one. – maxqua72 Apr 07 '13 at 12:07