Announcement Announcement Module
Collapse
No announcement yet.
multiple action beans? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • multiple action beans?

    Is this documented? Can you use multiple action beans within an action-state? The following seems to work.
    Code:
    <webflow id="adminSignInFlow" start-state="adminSignInViewSetup">
        <action-state id="adminSignInViewSetup">
            <action bean="adminSignInViewSetup" method="setupForm" />
            <action bean="adminSignInViewSetup" method="setUpReferenceData" />
            <transition on="success" to="adminSignInViewSetup" />
        </action-state>
    What's the protocol? Do they both have to return success() for the who action-state to succeed?

  • #2
    Hmm, I don't understand how that was working since it was transitioning back to itself. I fixed it and now it's not doing the setUpReferenceData:
    Code:
    <webflow id="adminSignInFlow" start-state="adminSignInViewSetup">
        <action-state id="adminSignInViewSetup">
            <action bean="adminSignInViewSetup" method="setupForm" />
            <action bean="adminSignInViewSetup" method="setUpReferenceData" />
            <transition on="success" to="adminSignInView" />
        </action-state>
    
        <view-state id="adminSignInView" view="adminSignInView">
            <transition on="submit" to="bindAndValidate" />
        </view-state>

    Comment


    • #3
      I'd recommend reviewing the javadoc for ActionState, it describes the behavior here.

      Basically the actions execution in a ordered chain until one returns a result that matches a state transition.

      For your case where you've got a reference data method, I'd recommend moving that to a view state setup action--to setup the view before rendering with neccessary drop down data, for example.

      Keith

      Comment


      • #4
        Ok, thanks.

        Comment


        • #5
          Originally posted by Keith Donald
          I'd recommend moving that to a view state setup action--to setup the view before rendering with neccessary drop down data, for example.

          Keith
          Does that entails overriding setupForm (), inserting code that does the lookup of the reference data?

          Comment


          • #6
            Here's what my -flow.xml file looks like now.
            Code:
            <webflow id="adminSignInFlow" start-state="adminSignInViewSetup">
                <action-state id="adminSignInViewSetup">
                    <action bean="adminSignInViewSetup" method="setupForm" />
                    <transition on="success" to="adminSignInView" />
                </action-state>
            
                <view-state id="adminSignInView" view="adminSignInView">
                    <setup bean="adminSignInViewSetup" method="setUpReferenceData" />
                    <transition on="submit" to="debugView">
                        <action bean="adminSignInViewSetup" method="bindAndValidate" />
                    </transition>
                </view-state>
            
                <view-state id="debugView" view="debugView">
                    <transition on="end" to="end" />
                </view-state>
            
                <end-state id="end" />
            </webflow>
            Prior to this version I had success and error transitions in the bindAndValidate action-state. Now the error view isn't called and it goes back to the adminSignInView if the bindAndValidate sets an error. Since I'm still mostly stumbling around in the dark I can't say if this is the correct way to do things. Here's my FormAction:
            Code:
            public class
            AdminSignInViewSetup extends FormAction &#123;
                public
                AdminSignInViewSetup&#40;&#41; &#123;
                    setFormObjectClass&#40;AdminSignIn.class&#41;;
                    setFormObjectName&#40;"adminSignIn"&#41;;
                    setFormObjectScope&#40;ScopeType.FLOW&#41;;
                &#125;
            
                public Event
                setUpReferenceData&#40;RequestContext ctx&#41; throws Exception &#123;
                    ctx.getFlowScope&#40;&#41;.setAttribute&#40;"facil", "wmf"&#41;; 
            
                    return&#40;success&#40;&#41;&#41;;
                &#125;
            &#125;
            Here's my view/jsp:
            Code:
            <body>
            <div align="center">
            <form name="adminSignInView" method="post">
            <spring&#58;bind path="adminSignIn.name">
            <input name="name" type="text" />
            <c&#58;if test="$&#123;status.error&#125;">
            <span class="err"><c&#58;out value="$&#123;status.errorMessage&#125;" /></span>
            </c&#58;if>
            </spring&#58;bind>
            <span></span>
            <input type="submit" value="submit" />
            <input type="hidden" name="_flowExecutionId"
                    value="<c&#58;out value='$&#123;flowExecutionId&#125;'/>" />
            <input type="hidden" name="_eventId" value="submit" />
            <input type="hidden" name="_currentStateId"
                    value="<c&#58;out value='$&#123;currentStateId&#125;'/>" />
            </form>
            </div>
            
            <div>
            Facil&#58; <c&#58;out value='$&#123;facil&#125;'/>
            </div>
            
            <div>
            <h4>Params&#58;</h4>
            <c&#58;forEach var='v' items='$&#123;paramValues&#125;'>
                <ul>
                <%-- Show the key, which is the request parameter name --%>
                <li><b><c&#58;out value='$&#123;v.key&#125;'/></b></li>
                <%--
                     Iterate over the values, a String&#91;&#93;,
                     associated with this request parameter
                  --%>
                <c&#58;forEach var='vv' items='$&#123;v.value&#125;'>
                    <%-- Show the String value --%>
                    <c&#58;out value='$&#123;vv&#125;'/>
                </c&#58;forEach>
                </ul>
            </c&#58;forEach>
            </div>
            
            <div>
            <h4>Headers</h4>
            <c&#58;forEach var='v' items='$&#123;headerValues&#125;'>
                <ul>
                <%-- Show the key, which is the request header name --%>
                <li><b><c&#58;out value='$&#123;v.key&#125;'/></b></li>
                <%-- Iterate over the values, a String&#91;&#93;, --%>
                <%-- associated with this request header --%>
                <c&#58;forEach var='vv' items='$&#123;v.value&#125;'>
                    <%-- Show the String value --%>
                    <c&#58;out value='$&#123;vv&#125;'/>
                </c&#58;forEach>
                </ul>
            </c&#58;forEach>
            </div>
            
            </body>

            Comment


            • #7
              It's correct if it's doing what you want it to do! :-)

              What do you mean "now the error view isn't called?" If you need your flow to respond to the result of a bind and validate action, e.g to route to a custom error view state, then you'll need to put back your action state definition.

              The transition action like what you have above is there as a convenience to execute an action after a transition is matched but before that transition is executed. If a "transition action" returns success(), the transition to the target state is allowed -- anything else causes the source state to reenter. This is useful for a typical "bindAndValidate" where data binding and validation happens and if there is a error, the form view is reshown.

              Courteny - no that does not entail overriding setupForm -- a view setup action executes an Action, which could trigger invocation of a method like 'setupReferenceData' on a multi action instance.

              Keith

              Comment


              • #8
                Originally posted by Keith Donald
                What do you mean "now the error view isn't called?" If you need your flow to respond to the result of a bind and validate action, e.g to route to a custom error view state, then you'll need to put back your action state definition.
                It's good the way it is now. Before there was a bindAndValidate action-state that had transitions for error and success. The way it is now with it redisplaying the form is better. For debugging I have the forEach loops in the adminSignInView now as well, so on sign in error I see that stuff.

                My remaining problem now is that the success view has a
                Code:
                <meta http-equiv="refresh" content="5">
                in the head and I have no idea how to keep it from going back to the sign in page on the refresh; it needs to stay on the success view page.

                Comment


                • #9
                  Originally posted by Keith Donald

                  Courteny - no that does not entail overriding setupForm -- a view setup action executes an Action, which could trigger invocation of a method like 'setupReferenceData' on a multi action instance.

                  Keith
                  Sorry, I am translating the xml flows to java-base flows and I am beginning to see my error, which is thinking that

                  <setup bean="xxxxx" method="xxx" />

                  is something other than a "addActionState (xxxxx)".

                  Ok, it is just a plain old action state that gets executed (loading reference data) before executing a view state. So, in a Java-base flow it will look something like the following?

                  //Prepare to display a new form.
                  //It basically initializes the binder so that all property editors are available for form display.
                  addActionState ("setupForm", action (PersonFormAction.class), on(success(),"setupReferenceData"));


                  //Lookup reference data to display in the form drop down box
                  addActionState ("setupReferenceData", action (PersonFormAction.class), on (success(), "displayForm"));

                  //Display the input form with loaded reference data.
                  addViewState ("displayForm", "NewPerson", new Transition[] {on(submit(), "bindAndValidateForm")});

                  //Bind and validate input data from the form.
                  addActionState ("bindAndValidateForm", method ("bindAndValidate", action (PersonFormAction.class)),
                  new Transition[] {on (error(), "displayForm"), on (success(), ON_SUBMIT)});

                  Correct?

                  Comment


                  • #10
                    As an aside: the original action state can be made to work using named actions:

                    Code:
                    <action-state id="adminSignInViewSetup">
                       <action name="setup" bean="adminSignInViewSetup" method="setupForm" />
                       <action name="referenceData" bean="adminSignInViewSetup" method="setUpReferenceData" />
                       <transition on="referenceData.success" to="adminSignInView" /> 
                    </action-state>
                    Note how both actions now have a name. Also note how there is only a transition for the success event of the referenceData action. This will result in the following behaviour:

                    1) The setupForm action is executed and it returns "success". Since there is no transition matching "setup.success", the action state will continue action execution with the next action.
                    2) The setUpReferenceData action is executed and it returns "success". Since the there is a matching transition "referenceData.success", the action state stops action execution and transitions to the next state: "adminSignInView".

                    Ofcourse you could also add the necessary error transitions if needed: "setup.error" and "referenceData.error".

                    As you can see named actions give you a way to ignore the result of an action and continue executing other actions in the action state.

                    Erwin

                    Comment


                    • #11
                      Originally posted by klr8
                      ... As you can see named actions give you a way to ignore the result of an action and continue executing other actions in the action state.

                      Erwin
                      Yes, that is slick.

                      Comment


                      • #12
                        Ohh I forgot about that! you can thank Erwin for that feature :-)

                        Comment


                        • #13
                          Thanks Erwin

                          Comment

                          Working...
                          X