Wednesday, March 25, 2009

Quick Note about JSF, ADF and Postbacks

Unlike ADF, in pure JSF it appears there is no AdfFacesContext.postback context element to use to determine if you are currently in a post back or not. To determine postback you have to do some odd stuff.

So what is a postback? In short it is when a JSF page submits and it stays right where it is. In other words the action of the form is set to post to itself, passing all of its named fields as parameters. When the Faces Servlet sees this occurring it alters its “behavior”. The normal JSF request lifecycle has 7 or 8 phases when it is drawn out for others to see…but all these phases only come into play on a post back. When you first call a JSF page, all that you actually get is the first and the last phase…everything else is left out.

These postbacks are extremely important in the Rich Component world though. You have to postback in order to implement a very nice way to do AJAX functionality without having to make others who want to use your components add servlets to their web.xml.

5 comments:

Christian said...

You wrote:
"To determine postback you have to do some odd stuff."
Which is this odd stuff?

I am facing this issue on JSF 2.0.
It seems that just my second click on commandButtons or commandLinks is evaluated as a Postback after a rendering from a different form.

Any suggestions?

Michael A. Fons said...

Christian,

I am sorry to say that I have never dealt with JSF 2.0 at all. But I am interested in your problem.

Is the problem that you do not want postback behavior on your second click, or that you DO want postback behavior on your FIRST click?

If I remember correctly (it was a quick read somewhere on the internet) in order to determine if they had a postback they created a hidden field on their screen, and checked it for a value which they placed there during the initial screen encoding.

Implementing a phase listener and detecting one of the other phases that only comes during a postback and setting some kind of flag or request scope boolean variable would probably be better.

So please let me know more about your problem. I have been working with JSF 1.1 and 1.2 long enough I may be able to help you.

Michael F.

Christian said...

Thanks for your reply Michael.

I have a multi form xhtml page.
When I click on a button I want to rerender just a part of the application (Ajax approach).

To do that for example I use the JSF 2.0 tag: f:ajax

This rerendering happens just at the second click because the first one is not a postback so the 2-5 JSF phase are skipped (I implented a LifeCycleListener that logs the phases).

How can I force a postback in the beforePhase method for example?

Thanks for the interest,
Christian

Michael A. Fons said...

Here, I believe, is the secret for getting a postback:
with AJAX you can do a GET or a POST and still have it be a postback, but either way there needs to be a name-value pair in the request url to match every html "form" tag (e.g., select, input, textarea, etc) with a "name" attribute. So, for example, if your page renders

Michael A. Fons said...

Sorry, blogger cut off my entry. If you have two inputs, then your url must have both name-value pairs of these two fields in order to register as a postback.

If you do not have control of the url (if you are using the ajax tag, for example, then this could be a problem).

I would look at your url and see what request url is being produced by either looking at your httpservletrequest (from the external context), or using something like firebug.

In JSF 1.2 there was a standardized name for a particular hidden field that always was put into the page by jsf. I wonder if this is still there in jsf 2.0...

Maybe this 2.0 ajax tag is not ready for prime time yet? If so there are only about 80,000,000 other ways to do ajax in jsf.