Can a faces flow be started from within a Servlet?
Asked Answered
G

1

2

I have a service, accessed by a servlet, which redirects the user to a login screen. The backing beans' scope is currently being changed from @ConversationScoped to @FlowScoped, as it's easier to handle.

Is there a way to initialize a faces flow directly from within a servlet, without the indirection through an implicit action or a JSF forward/redirect?

I am aware that @FlowScope is a JSF (2.2) scope and I was wondering if there might be a way to e.g. extend the FacesServlet or something similar.

As a workaround, I currently just added view with a button, which makes a JSF forward to enter the flow directory, but I am trying to avoid this.

Update
I tried many approaches to 'automatically' forward into a flow, without having to click on any button, but I always get a No active contexts for scope type javax.faces.flow.FlowScoped. Here my approaches:

  1. f:viewAction

    <f:metadata>
      <f:viewAction action="myFlow" />
    </f:metadata>
    

    This one seems to be executed too early (in any case).

  2. f:event

    <f:event type="preRenderView" listener="#{myBean.forwardToMyFlow()}" />
    

    The method in the bean returns the same outcome as in f:viewAction.

  3. Navigation case

    <navigation-rule>
      <from-view-id>/myView.xhtml</from-view-id>
      <navigation-case>
        <from-outcome>myFlow</from-outcome>
        <to-view-id>/myFlow/myFlow.xhtml</to-view-id>
        <redirect />
        <to-flow-document-id />
      </navigation-case>
    </navigation-rule>
    

What am I missing?

Geist answered 16/1, 2015 at 13:55 Comment(2)
Nothing wrong with having a front controller to a flow although, If I'm reading the specification properly, you should be able to directly reference the first view of the flow; the spec says that the necessary @FlowScoped beans must be initialized on entry to the first node in a flowCharkha
@Charkha Thanks for your reply and sorry for the delay, I have been off for a while. I found the reference in the spec, you mentioned, but I still could not get it to work. I always get a ContextNotActiveException...Geist
G
5

I finally found a solution, after reading specs and fiddling around with flows!
I am having a page where I simply have:

<f:metadata>
    <f:viewAction action="#{bean.initFlow}" />
</f:metadata>

So far so good, but the trick is inside the method, where you have to 'manually' initialize the desired flow by doing the following:

public String initFlow(){
   FacesContext context = FacesContext.getCurrentInstance();
   FlowHandler handler = context.getApplication().getFlowHandler();
   handler.transition(context, null, handler.getFlow(context, "", "flow-name"), null, "");
   return "flow-name";
}

The transition method 'activates' the named flow and makes it available, so that you then can forward to the entry point of the flow.
Please note, that even if it looks like a normal forward, viewAction always does a redirect!

Geist answered 25/3, 2015 at 14:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.