5

Once I've entered a Faces Flow, I want to exit it by going to any page that is not part of the flow.

The problem is that the flow is not destroyed if I go outside, for example via an h:link. Indeed, if I click again on a h:commandButton whose action is the flowId, I go back to the previous flow instead of creating a new flow.

How to exit a flow without having the user to click explicitly on a h:commandButton whose action corresponds to the return node of the flow ? Is it even possible ?

Edit:

Let's take this flow for example (from the JEE 7 samples)

@Produces @FlowDefinition
public Flow defineFlow(@FlowBuilderParameter FlowBuilder flowBuilder) {
    String flowId = "flow1";
    flowBuilder.id("", flowId);
    flowBuilder.viewNode(flowId, "/" + flowId + "/" + flowId + ".xhtml").markAsStartNode();

    flowBuilder.returnNode("taskFlowReturn1").
            fromOutcome("#{flow1Bean.returnValue}");
    flowBuilder.returnNode("goHome").
            fromOutcome("#{flow1Bean.homeValue}");

    flowBuilder.inboundParameter("param1FromFlow2", "#{flowScope.param1Value}");
    flowBuilder.inboundParameter("param2FromFlow2", "#{flowScope.param2Value}");

    flowBuilder.flowCallNode("call2").flowReference("", "flow2").
            outboundParameter("param1FromFlow1", "param1 flow1 value").
            outboundParameter("param2FromFlow1", "param2 flow1 value");

    return flowBuilder.getFlow();
}

The flow will be terminated if the user clicks on

<h:commandButton id="index" value="home" action="goHome" />

or

<h:commandButton id="return" value="return" action="taskFlowReturn1" />

But what if the user clicks on

<h:link outcome="someOutcomeUnrelatedToTheFlow"/>

Or if the user changes the url in the browser, without removing the jfwid? It seems the flow isn't terminated but the user is actually browsing outside of the flow.

That seems a bit odd to me: I can't find any way to exit the flow (and release the backing beans) without a specific action from the user on a commandButton/commandLink.

Btw: I'm testing this on WildFly 8 CR1.

thomas.g
  • 3,894
  • 3
  • 29
  • 36

1 Answers1

2

You are right. In the current version, the spec requires to navigate using UICommand components to determine if the flow is exited or not. However, this is not sufficient for any decent usage scenario where navigation happens using GET.

Notwithstanding the specs conceptual gap, a solution may be implemented and I expect to see one in upcoming versions of JSF libraries (actually, OmniFaces is a good bet, as BalusC and Arjan focus on fixing stuff that was left out in the spec ;-) ).

Technically speaking, a solution may look like this: The jfwid param is already added when h:linkor h:button is used. So a PhaseListener could be used to end the current flow if a view outside of the flows definition is requested. However, this is just a basic idea and there may be stumbling blocks which I did not consider yet.

So, to provide an answer to your question: Currently the only correct way to exit a flow is to either navigate to an exit node or to use h:commandLinkor h:commandButton for page navigation as this will also end a flow when a view outside of the flows definition is requested.

Community
  • 1
  • 1
tasel
  • 629
  • 5
  • 15
  • any chance this answer is outdated? – T.G Oct 06 '14 at 13:48
  • 1
    The JSF spec was not changed in the meantime, so the answer is not outdated yet. – tasel Oct 06 '14 at 15:28
  • btw. i've tried to create PhaseListener, that could end unneeded flow. I locate situation with GET request and active flow (because of jfwid present in link) however either in FlowHandler, and Flow (from getCurrentFlow()) has a method that would deactivate it (i can call finalizer method if it has been set, however i think, that flow itself is still active). Is it just me, or FacesFlow are really in alpha state? – T.G Oct 07 '14 at 08:23
  • While the answer is not outdated, I think it may have been misinterpreted. The original question states "I can't find any way to exit the flow (and release the backing beans) without a specific action from the user on a commandButton/commandLink." However, as BalusC noted, you can actually use anything that navigates to an exit node, including an h:link. So if you have an h:link with outcome="return-from-flow" and that is marked as a flow-return node, then it will end the flow. – Jon B Oct 08 '14 at 13:18
  • As to the final part of your answer: "... or to use h:commandLinkor h:commandButton for page navigation as this will also end a flow when a view outside of the flows definition is requested.". Is that right? In my case, it wont drop the flow state just because the user navigated to a view outside the flow. See: http://stackoverflow.com/questions/31295612/exiting-a-jsf-flow – RinaldoDev Nov 26 '15 at 02:57