Jim Driscoll's Blog

Notes on Technology and the Web

Mixing Ajax and full requests in JSF 2.0

leave a comment »

JSF 2.0 makes ajax pretty easy – but it can’t hide everything from you… It’s tempting to just add a few ajax tags into your page, and not worry too much about interactions – here’s one example of a problem you may run into.

Let’s say you’ve got a page with an input text, and a command button – like this:

   1 <h:form>
   2 <h:inputText value="#{blah.blah}">
   3 </h:inputText>
   4 <h:commandButton/>
   5 </h:form>

Now, we decide to add an ajax tag:

   1 <h:form>
   2 <h:inputText value="#{blah.blah}">
   3 <f:ajax event="blur"/>
   4 </h:inputText>
   5 <h:commandButton/>
   6 </h:form>

Can you spot what’s wrong with this example? When we push the button, we’re also blurring the inputText. That means that the ajax request is sent – but then, almost immediately, that request is canceled as the whole page is reloaded.

Is this a bad thing? For this simple example, not so much. There’s going to be a broken connection – and that can be a grim problem for a large server, especially if you start getting one on each page, for each use.

But the real issue is that you’ve just set up a race condition. Imagine instead you did this:


   1 <h:form>
   2 <h:inputText value="#{blah.blah}">
   3 <f:ajax event="blur" listener="#{bean.somethingthatchangesstate}"/>
   4 </h:inputText>
   5 <h:commandButton/>
   6 </h:form>

Now we’ve got a real problem from that race condition – did the listener execute? Maybe. Maybe is never a good answer in software.

So – what to do?

Probably the best solution is also the simplest:

   1 <h:form>
   2 <h:inputText value="#{blah.blah}">
   3 <f:ajax event="blur" listener="#{bean.somethingthatchangesstate}"/>
   4 </h:inputText>
   5 <h:commandButton>
   6 <f:ajax render="@form">
   7 </h:commandButton>
   8 </h:form>

Switching to ajax for the commandButton will now provide a predictable call sequence.

One more issue: When the two connections are submitted simultaneously, an error alert may be produced. I just updated that error to say: "The Http Transport returned a 0 status code. This is usually the result of mixing ajax and full requests. This is usually undesired, for both performance and data integrity reasons." What happens if you want to do this? Well, the error alert only shows up under two conditions, both of which must be true – the Project Stage must be Development, and there must be no error listener set. So, if you’re really sure you want to mix ajax and full requests, despite what I said above, just set up an error listener for your ajax code – you’ll want to anyway for a production environment.

As always, if you have questions, please ask in the comments.

(This article originally published on my java.net blog on October 2, 2009.)


Written by jamesgdriscoll

February 9, 2010 at 10:32 PM

Posted in ajax, JSF

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: