Announcement Announcement Module
Collapse
No announcement yet.
Problems with redirect to external page or to new flow Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Problems with redirect to external page or to new flow

    Hi,
    Firstly, I am rather new to Spring Webflow so any help would be appreciated.

    We're running in a Portlet environment and we just migrated from Webflow 1 to Webflow 2. (2.05 I believe). One of the functionality that did not port very well was flow redirects on end states.

    I see that there is a very short paragraph on the Spring Webflow Documentation but I was just wondering what would be good ways to solve my problem. I would deeply appreciate any examples of how to do this. (note the documentation suggests something along the lines of implementing a flow handler but I wasn't too sure on how to do this)

    There are two things that I need achieved from an end state.
    a) external redirect to some other jsp page
    b) flow redirect to another flow (basically ending the current flow and starting fresh!)

    Not too sure if we ever got 'a)' to work. I believe we had "view=X" (where X is the location of an external page) attribute on the end state. How do we achieve that in Webflow 2?

    As for 'b)', this was working in Webflow 1 where we did:
    end-state view="flowRedirect:some-other-flow" and that worked fine. How would I achieve this in Webflow 2?

    Any help would be GREATLY appreciated. Thanks in advance.
    Last edited by springster; Mar 17th, 2009, 01:40 PM.

  • #2
    From the schema at http://static.springframework.org/sc...bflow-2.0.xsd:

    The name of a view to render as a final flow response. Is often not specified when the caller handles this flow outcome and cares for the response.
    When specified, the value can be a flow-relative path to a view template:

    <pre>
    priceForm.jsp
    </pre>

    It can also be an evaluatable expression:

    <pre>
    ${flowScope.myViewExpression}
    </pre>

    The externalRedirect: prefix may be used to request a redirect to an external location, typically to interface with an external system or controller.
    External redirect query parameters may be specified using ${expressions} that evaluate against the request context.

    The supported formats for an encoded externalRedirect expression are:
    <pre>
    externalRedirect:<servlet relative path>
    externalRedirect:contextRelative:<context relative path>
    externalRedirect:serverRelative:<server relative path>
    externalRedirect:<fully qualified http:// or https:// URL>
    </pre>

    For example:
    <pre>
    externalRedirect:/hotels/index
    externalRedirect:http://someOtherSystem?orderId=${order.id}
    </pre>

    The flowRedirect: prefix may be used to redirect to another flow:
    <pre>
    flowRedirect:myOtherFlow?someData=${flowScope.data }
    </pre>

    For exotic usages, you may plug in a custom ViewFactory bean you define:
    <pre>
    ${myCustomViewFactory}
    </pre>

    <br>
    When this attribute is not specified, no final response will be issued.
    In this case, the caller is expected to handle this flow outcome.

    --
    I would also recommend checking out the JavaDocs for FlowHandler, too.

    Keith

    Comment


    • #3
      Thanks Keith. As I mentioned previously, we've been using end-state view="flowRedirect:someOtherFlow" in Webflow 1.0 but that stopped working in Webflow 2. Why is that so?

      Comment


      • #4
        Well, it should work! What is happening exactly? The more detail the better, even better if you can do some debugging around the cause, even better still if you submit a patch (all that helps us fix bugs faster, and we definitely can't fix bugs we don't know about :-))

        Keith

        Comment


        • #5
          Just saw this thread while looking for something else and wanted to add that I use both features successfully with SWF 2.0.5. This is from my flow definition file that all my flows inherit from:

          Code:
          <end-state id="leave_external" view="externalRedirect:${conversationScope.returnUrl}"/>
          <end-state id="menu_action" view="flowRedirect:${menuActions.getFlowId()}"/>
          The first end-state is called when a redirection to an external, non-SWF page is needed. The second is used when another flow needs to be called. Both get their value from a bean or flow variable (which has been set accordingly by previous actions), but a direct value should work as well.

          Comment


          • #6
            Note that I am in a portlet environment.

            Im looking into implementing flow handlers for this functionality now (I know its pretty crazy for something that seems so basic!) but I notice a difference between spring 2.0.6 and 2.0.5

            AbstractFlowHandler is defined in 2 different packages:

            org.springframework.webflow.mvc.portlet;
            org.springframework.webflow.mvc.servlet;

            the handleExecutionOutcome is implemented differently in 2.0.6. In 2.0.6, a String is the return type of the method in the servlet implementation whereas it is a boolean in the portlet implementation. Any ideas why?

            Comment


            • #7
              Could you please provide more detail on why flowRedirect is not working in your portlet environment, opening a JIRA so we can investigate it? FlowHandlers are optional constructs. You still should be able to use the end-state flowRedirect feature without issue.

              The JavaDocs should explain the reasoning behind the API signature.

              Keith

              Comment


              • #8
                I'm having the same problem in a portlet environment. I've been debugging the problem and can see that the EndState's doEnter -method is executed in the action phase and hence, these lines of code will never get executed:

                Code:
                if (finalResponseAction != null && canSendResponse(context.getExternalContext())) {			
                    ActionExecutor.execute(finalResponseAction, context);
                    context.getExternalContext().recordResponseComplete();
                			
                }

                The problem seems to be that end-states are executed in the action phase and therefore, the finalResponseAction will never get executed.

                Regards,
                Hampus

                Comment


                • #9
                  Yes, that is correct. I have taken a look at the 2.0.x code and support for processing flow and external redirects from web flow end-states in a Portlet environment is not implemented; I was mistaken before going from memory, and the code always sets us straight.

                  The 2.0.x solution is to implement the handleFlowExecutionOutcome operation on your Portlet FlowHandler that uses the ActionResponse to send the final redirect response. This has the benefit of decoupling the flow from a particular final response, but the downside is its another artifact to maintain separate from the flow as springster alluded to. This isn't terribly inconvenient, though, since you have to implement the FlowHandler anyway... see booking-portlet-mvc for an example.

                  It is possible for us to add back support for processing such redirect final response behaviors, but it would be a fairly significant piece of work for a 2.0.x maintenance release. I'd be more comfortable addressing that in the next major release. In any case, we need to create a JIRA on this to track this enhancement to our portlet support.

                  Keith
                  Last edited by Keith Donald; Mar 21st, 2009, 05:44 PM.

                  Comment


                  • #10
                    JIRA created

                    http://jira.springframework.org/browse/SWF-1080

                    This will require changes to portlet.FlowHandlerAdapter and EndState. The biggest issue with just doing it in 2.0.x is we can't distinguish between different types of allowed responses--e.g. rendering a view in a action request is a no-no but requesting a flow/external redirect is allowed. The current canSendResponse method simply checks the external context if a "any response is allowed" and the response has not already been completed... that's why the enhancement isn't terribly simple. I'm open to suggestions.

                    Keith
                    Last edited by Keith Donald; Mar 21st, 2009, 05:43 PM.

                    Comment


                    • #11
                      Ok, so how would I implement a FlowHandler? the handleExecutionOutcome only gets the id of the state that ended the flow. I can't see anyway of getting the view property from the end-state to appear in the handleExecutionOutcome. Any ideas or examples?

                      /Hampus

                      Comment


                      • #12
                        You don't get the view property from the end-state, that's flow internal. The idea is your flow handler is flow-specific and knows what to do for a given flow outcome. It can access flow output attributes which you can return from the flow using the output element.

                        Comment


                        • #13
                          Hampus,

                          Also, if you're already using Web Flow 2.0.x in a portlet environment, I would have thought you are implementing a FlowHandler already anyway. What else are you mapping to in your Spring Portlet MVC config? See the booking-portlet-mvc sample which maps to a ViewFlowHandler for the view portlet mode that starts the view flow. It doesn't implement handleExecutionOutcome, because its not needed, but thats where you'd do it.

                          Keith

                          Comment


                          • #14
                            So that leads me to a FlowHandler per flow which, in my case, will be a lot of FlowHandlers.
                            But you said that you will address this in a major release? Would that be in a 3.0 release perhaps? If so, any clues on the time frame for the 3.0?

                            /Hampus

                            Comment


                            • #15
                              Yes, I'm using a custom FlowHandler which takes the property of a default flow to start but that FlowHandler is reused for all my portlet applications and the only thing that needs to be reconfigured is the property of the default flow. I guess, I could add property view-mappings as well but it would be a custom solution and if you are addressing this in a near future, maybe I'll wait.

                              /Hampus

                              Comment

                              Working...
                              X