Search code examples
jsfjakarta-eejsf-2primefacesnavigation

Redirecting browser back button in jsf 2.0


I am writing an application using Primefaces 3.4.1, Jboss AS 7.1 and MyFaces CODI. The problem that I got is that I am using conversation scope provided by CODI and I need a way to deal with the browser back button once the conversation ends.

More precisely- when the conversation ends and the user is on a different page (think about it like a wizard finishing and making a commit to database) if the back button is pressed I recieve the following exception:

javax.ejb.EJBTransactionRolledbackException

Ideally, since the conversation is finished I would like this to redirect back to some other page (menu, dashboard).

Can this be done with JSF 2.0 navigation rules?

EDIT:

I have created a navigation rule like this:

<navigation-rule>
    <from-view-id>/page1.xhtml</from-view-id>
        <navigation-case>
            <from-outcome>outcome1</from-outcome>
            <to-view-id>/page2.xhtml</to-view-id>
            <redirect/>
        </navigation-case>
        <navigation-case>
            <from-outcome>*</from-outcome>
            <to-view-id>/dashboard.xhtml</to-view-id>
            <redirect/>
        </navigation-case>
</navigation-rule>

Hoping that this will make the redirection to dashboard.xhtml if we press back button. I assumed that there is a different action fired in the back end when you press it. Clearly I assumed wrong. Is it any way one could catch whatever is sent by the bakc button using these cases? Possibly with tag?

UPDATE 1:

Apparently the back button from the browser will not trigger the JSF navigation case. Is it clear what it will trigger? I implemented the following filter: https://stackoverflow.com/a/10305799/1611957 What wil it trigger now? Does that make the job of catching it easier?


Solution

  • I have finally managed to resolve the issue and it may be helpful for others:

    The first thing to do is to make sure that you are not caching pages. You can do it with the filter explained here:

    https://stackoverflow.com/a/10305799/1611957

    After that you will know that the page is going to be rendered, so you need to do a check before rendering if your conversation beans are instantiated correctly. How to do such a check is explained here:

    https://stackoverflow.com/a/7294707/1611957

    The code that I used is similar to the code posted by BalusC in this question:

    <f:metadata>
        <f:event type="preRenderView" listener="#{authenticator.check}" />
    </f:metadata>
    

    With the java code:

    public void check() {
        if (someCondition) {
            FacesContext facesContext = FacesContext.getCurrentInstance();
            NavigationHandler navigationHandler =
                facesContext.getApplication().getNavigationHandler();
            navigationHandler.handleNavigation(facesContext, null, "outcome");
        }
    }
    

    With that you will dispatch the JSF navigation rule for the "outcome"

    <navigation-rule>
        <from-view-id>*</from-view-id>
        <navigation-case>
            <from-outcome>outcome</from-outcome>
            <to-view-id>/defaultPage.xhtml</to-view-id>
            <redirect/>
        </navigation-case>
    </navigation-rule>
    

    And this is how you can gracefuly handle back button with JSF2.