2

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?

Community
  • 1
  • 1
bjedrzejewski
  • 2,378
  • 2
  • 25
  • 46

3 Answers3

4

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.

Community
  • 1
  • 1
bjedrzejewski
  • 2,378
  • 2
  • 25
  • 46
1

We are using @ConversationRequired for it.

Dar Whi
  • 822
  • 5
  • 14
  • Is that a CODI notation? Also, does it allow you to redirect? It sounds exactly like the thing I need. – bjedrzejewski Oct 29 '12 at 09:18
  • I can't find much about it in CODI documentation- could you give me some more information about it? – bjedrzejewski Oct 29 '12 at 09:48
  • Per default it doesn't do a redirect, but we just integrated it that way. I guess because you would get an issue with wizards in a dialog (so it replaces the View-Root with the view of the entry point). You just need to read a bit source-code which is in ConversationRequiredUtils.ensureExistingConversation. I'm sorry that I'm not allowed to share how we are using it. – Dar Whi Nov 03 '12 at 00:45
  • It would be better if you explain how you use it. – Luiggi Mendoza Apr 25 '13 at 22:15
-1
This worked for me.
You can add the below code in between your <head> </head> tag

<script>
    window.location.hash = "no-back-button";
    window.location.hash = "Again-No-back-button";//again because google chrome don't insert first hash into history
    window.onhashchange = function() {
        window.location.hash = "no-back-button";
    }
</script>
Ajay
  • 570
  • 8
  • 17
  • This does not answer the question at all. Have you read the question beyond its title? It clearly says *"Ideally, since the conversation is finished **I would like this to redirect back to some other page** (menu, dashboard)."*. But your answer basically completely kills the default behavior of the back button and does not redirect back to "some other page". – BalusC Oct 05 '20 at 11:23