tags:

views:

187

answers:

1

Hi there,

I'm using JSF (Mojarra 1.2) with Richfaces (3.3.2) within some facelets which are used as portlets (I'm using the Jboss Portlet Bridge 2.0 here). Now I'm facing something strange: I've got an actionlistener on my <h:commandButton> which is triggered, when the button is clicked but when I simply reload the page, the action is executed everytime I load the page again. This happens only if I already triggered the action before. Is this behaviour normal?

I should notice that Spring 2.5 is used to manage my beans, the mentioned beans are session-scope beans, maybe this is a interessting point?!

+2  A: 

Yes, reloading a HTTP POST request will execute the HTTP POST request again and thus trigger all associated server-side actions again. This issue affects all webapplications in general and is not per se related to JSF.

A well known fix to this is the POST-Redirect-GET (PRG) pattern. Basically you need to redirect the POST request to a GET request immediately after processing the action, so that the result page will be delivered by a HTTP GET request. Refreshing this HTTP GET request won't execute the initial HTTP POST request anymore.

This pattern has however one caveat: since it concerns a brand new request, all request scoped beans are garbaged and renewed in the new request. So if you'd like to retain the data in the new request, you would need to either pass them as GET parameters or to store it in the session scope. Usually just reloading the data in bean's constructor is sufficient. But since you mention to use session scoped beans only (which is however not the best practice, but this aside), this shouldn't be a big concern for you.

Turning on PRG in JSF is relatively easy, just add the following entry to the associated <navigation-case>:

<redirect />

Or if you prefer to fire it programmatically, then make use of ExternalContext#redirect() in the bean's action method:

public void submit(ActionEvent event) {
    // ...
    FacesContext.getCurrentInstance().getExternalContext().redirect(someURL);
}
BalusC
Thanks for your reply BalusC - but if I only switch to another portlet page and after that back to my JSF portlet, which still holds the objects in the session bean, then the action is executed too. If I'm not totally wrong this shouldn't happen or am I wrong?
asrijaal
One note: I use only session scoped beans here because it fits well in my little portlet which only shows a little bit of data. Well I'm talking at plurals, its only one JSF page with one backing bean.
asrijaal
Have you implemented the `<redirect />` ?
BalusC
No - in case I don't have a navigation rule, just got one page where I render a panel group with my dataTable. Is the problem caused by this circumstance?
asrijaal
Oh, is it an ajax based request?
BalusC
Yea it is. I noticed right now, that the action is executed twice.
asrijaal
Ok I solved it and it hasn't anything to do with my JSF page, my programmatic logic was - well - stupid? Anyways thank you BalusC
asrijaal
You're welcome.
BalusC