views:

38

answers:

3

Hi all,

I wish to forward an action to the next configured action but prior to that to create a new ActionForm instance and have it associated with the forwarded action:

Psuedo code follows :

public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {

    ActionForward forwardPage = mapping.findForward("success");


    // Some Code....
    ....
    ....

    // finally
    MyActionForm form = new MyActionForm();

    form.setSomeProp(...);
    form.setAnotherProp(...);

    forwardPage.doSomeMagicAndAssociateWith(form);

    return forwardPage;

}

Sorry if its a dumb question, I'm new to all this and have not been able to find an answer...

Thanks

EDIT 1:

Just to clarify: ActionForwarded to "success" had existed prior to the new feature that I must now add.

I just wish to, in certain flows, come in before the initial flow (here called "success") and do some computations after which in case of success [ :-) ] to forward the flow to the "success" action.

Hope my point is clearer now.

+1  A: 

In the action, you can change field values of the ActionForm passed in parameter, but you can't create a new ActionForm and associate it with the next JSP page.

If you want to reset all data in the form beetween calling the forwarded page, you can do something like "form.reset();" or "form.clear();", creating this method in your Form class.

If you need fields in the success page that are not in the form, you can use the "request" object to store theses fields.

Benoit Courtine
+1  A: 

Assuming a simple configuration in struts-config like the following:

<action path="/action1"
  type="...."
  name="form1"
  scope="...">
    <forward name="success" path="/action2.do"/>
</action>

<action path="/action2"
  type="...."
  name="form2"
  scope="...">
        ...
</action>

To forward to your second action, you just use return mapping.findForward("success"); and the flow will be forwarded to the second action. Assuming you have some configs like the following for each ActionForm:

<form-beans>
  <form-bean name="form1" type="..." />
  <form-bean name="form2" type="..." />
</form-beans>

then what you want is to get your hand on form2 and fill it with data before doing the forward.

You can off course do that since each form (be it form1 or form2) are bounded to the specified scope with the specified name, but that will be interfering with Struts normal flow and it is a bad practice (you must really know how Struts works before stepping in and stealing the show). That's is why I won't tell you how to do it.

What I recommend you to do instead is to decouple as much as you can the two actions. Each action will do its thing, no action will depend on data being pre-filled by another action.

To do that, move your "magic" code in your second action and do the operations once you are there. If you only need to do the operations in action 2 if you come from action 1 then you can add a flag to the configuration:

<forward name="success" path="/action2.do?theFlag"/>

and test for that in action 2 (request.getParameter("theFlag") != null for example). This way, you have the two actions tied only by the flag.

One other thing you can do is use DispatchAction classes. This is a collection of execute methods that could all share the same form so you forward from one method to the other without having multiple forms to manage.

EDIT: Based on your comment: "...my new feature, needs to execute some logic prior to it and only if successful go on to execute the "original' action." do you mean you just need something like this:

public ActionForward execute(ActionMapping mapping, ActionForm form, 
          HttpServletRequest request, HttpServletResponse response) throws Exception {
  ActionForward forwardPage = mapping.findForward("success");

  // Some Code....

  boolean isSuccess = runLogicAndReturnStatus();

  if (isSuccess) {
    return forwardPage;
  } else {
    return mapping.findForward("error"); // or return to the same page (input page)
  }
}

If that is it, why do you need to create a new ActionForm instance and have it associated with the forwarded action?

dpb
@dpb - I am not talking about stealing the show. Please take a look at the new Edit I have added to the question. Perhaps it will help us both. Just the same thanks for you lengthy answer.
Yaneeve
@Yaneeve: what do you mean by [ActionForwarded to "success" had existed prior to the new feature that I must now add.]? Are you talking about mapping.findForward? That is not where your forward takes place, that is where the destination for your forward is retrieved. Forward will happen in the action servlet, long after you do return forwardPage. I'm not sure I understand what you want to do.
dpb
@dpb - I mean that it had been written for a specific purpose a long (long) time ago. Now, my new feature, needs to execute some logic prior to it and only if successful go on to execute the "original' action.
Yaneeve
@Yaneeve: I edited my answer
dpb
@dpb - realizing my question sounded stupid and finally stumbling upon the answer I had wanted I posted it down as answer. Feel free to comment on it...
Yaneeve
A: 

I have managed on my own. Maybe my solution will explain what I am not sure I had been able to in my question...

Say this is my struts-config.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd"&gt;
<struts-config>
    <data-sources>
    </data-sources>
    <!-- ================== Form Beans ================ -->
    <form-beans>
        <form-bean name="FirstForm"
            type="com.blahblah.forms.FirstForm" />  
        <form-bean name="SecondForm"
            type="com.blahblah.forms.SecondForm" />

            <form-bean name="NewForm"
            type="com.blahblah.forms.NewForm" />
    </form-beans>   
    <!-- ================== Action Mapping Definitions ================ -->
    <action-mappings>       
        <action path="/pages/First" name="FirstForm"
            type="org.springframework.web.struts.DelegatingActionProxy" scope="request">
            <forward name="success" path="/pages/Second.do" />
        </action>
        <action path="/pages/Second" name="SecondForm"
            type="org.springframework.web.struts.DelegatingActionProxy" scope="request">
            <forward name="doSomthing" path="/pages/DoSomthing.jsp" />
        </action>

        <action path="/pages/New" name="NewForm"
            type="org.springframework.web.struts.DelegatingActionProxy" scope="request">
            <forward name="success" path="/pages/First.do" />
        </action>
    </action-mappings>
</struts-config>

FirstForm, FirstAction, SecondForm and SecondAction had existed previous to my feature and I had NO wish to intervene within their code...

The NewAction's execute() does the following:

public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {

    ActionForward forwardPage = mapping.findForward("success");

    // do some coding

    FirstForm firstForm = new FirstForm();
    firstForm.setX(...);
    firstForm.setY(...);
    request.setAttribute("FirstForm", firstForm);

    return forwardPage;
}
Yaneeve