Craig - I have not see a followup to my message on the topic of action chaining. I'm just curious if you have more insight into the kinds of things I use it for and how Struts should or should not be handling it.
Thanks, Erik ----- Original Message ----- From: "Erik Hatcher" <[EMAIL PROTECTED]> To: "Struts Developers List" <[EMAIL PROTECTED]> Sent: Wednesday, April 24, 2002 12:26 PM Subject: Re: ActionServlet re-populates form upon Actoin => Action call > I'm going to have to chime in here a bit. I find Action chaining a very > powerful feature. I don't use it extensively, but it comes in very handy to > keep, say, a DeleteAction seperate from the action to regenerate the results > (GetResultsAction, for example). This allows me to put a "delete" button on > a record set listing, or on the record detail page, with the action mapping > having a different path between the two, but both map to the DeleteAction > class. Then the local forward for that mapping says whether to go back to > the listing page or to some other page, and can involve using another action > for that forward in the case of regenerating the listing page. > > Making discrete actions that do only a very simple thing and return > "success" allows me to re-use them and glue them all together in > struts-config in ways that the actions don't need to know about. In the > example above, the DeleteAction should not also be responsible for > regenerating the result set for the listing page, since the listing page may > not be where it goes after deleting, nor should the DeleteAction do anything > at all but delete and return "success". How does what I'm saying fit into > what you're saying, Craig? > > I'm not doing anything funky with setting form data or in some way modifying > a form in those actions that are chained so I haven't experienced the > re-populate problem being discussed, but I did want to make it heard that > action chaining seems to be one of the strong points of Struts, at least to > me it is. I support the efforts for improving how action chaining works, > although I don't have any specific insight into how that should be > implemented at the moment. I'm out of the loop with the latest Struts > codebase and the project I'm currently working on is using a nightly build > from several months ago - so it would be premature for me to speculate on > what would need to be modified without reacquainting myself with the > enormous changes that have taken place since then. > > Doesn't Ted do this action chaining in some of examples? > > Erik > > ----- Original Message ----- > From: "Craig R. McClanahan" <[EMAIL PROTECTED]> > To: "Struts Developers List" <[EMAIL PROTECTED]> > Sent: Wednesday, April 24, 2002 11:48 AM > Subject: Re: ActionServlet re-populates form upon Actoin => Action call > > > > > > > > On Wed, 24 Apr 2002, Nicolas De Loof wrote: > > > > > Date: Wed, 24 Apr 2002 17:29:25 +0200 > > > From: Nicolas De Loof <[EMAIL PROTECTED]> > > > Reply-To: Struts Developers List <[EMAIL PROTECTED]> > > > To: Struts Developers List <[EMAIL PROTECTED]> > > > Subject: Re: ActionServlet re-populates form upon Actoin => Action call > > > > > > I agree with Terrence about the poor way you can couple Actions. > > > > > > It would be interesting to chain two Actions, basing chaining on the > > > "ActionForward" the first one returns, and assuming that request the > > > FormBean is populated only once. > > > > > > I understand it is a different behaviour of current "forward" mecanism > that > > > allow to forward to any URL. > > > > > > I would like to be able to define a forward that would be typed to > "chain", > > > so that the associated action would be called without request parsing. > So we > > > could reuse elementary actions working on request or session datas, and > > > declare request-handling actions for application URLs, using a > declarative > > > way to define actions chaining. > > > > > > Perhaps it is what the workflow extension is assuming ? > > > > > > > In my own world view, actions are designed to be called by HTTP requests, > > not by other actions. > > > > Adding some sort of action chaining mechanism would address this concern. > > However, IMHO, a better design is to refactor the logic you are trying to > > share into separate classes that can be directly invoked from the first > > action (after doing its own thing) and from the second action. > > > > Imagine S is a chunk of shared logic that is the reason you want to chain > > in the first place. > > > > Instead of: > > > > A1 --> A2 (contains S) > > > > think about: > > > > A1 (do its own processing, then call S) > > A2 (calls S) > > > > If you need the logical-physical mapping support for calling S without > > knowing its class name, that can be created fairly easily as well. > > > > Servlet chaining was the worst thing that ever happened to servlets (in > > the pre-Servlet-2.0 days). I'm glad it never got supported in the real > > servlet API, and am not real anxious to see us implement it in Struts. > > > > Craig > > > > > > > > > > ----- Original Message ----- > > > From: "Terrence Xavier" <[EMAIL PROTECTED]> > > > To: "'Struts Developers List'" <[EMAIL PROTECTED]> > > > Sent: Wednesday, April 24, 2002 4:16 PM > > > Subject: RE: ActionServlet re-populates form upon Actoin => Action call > > > > > > > > > > Dear Martin, > > > > > > > > Thanks for your reply. Although you raise some good points, we still > > > > have some trouble understanding the logic behind Struts' behaviour. > > > > The Struts documentation encourages the use of the Form Bean across > > > > actions, thus coupling -- whether tightly or loosely -- the actions > > > > together. Or, you could look at it the other way around and say that > the > > > > Form Bean "provides a coupling mechanism". > > > > Although we agree that it is the natural behaviour of Struts to > > > > populate the form bean from the request parameters, we still have > trouble > > > > understanding why it is natural that this would be done with EVERY > > > > forwarded-to action (beyond the fact that the code currently does > this). > > > In > > > > fact, it seems very unnatural that it would be done over and over -- > > > > especially when one may wish to populate the form bean AFTER Struts > > > > populates it from the request parameters. > > > > I don't think that having one Action set a Form Bean attribute and > > > > having another Action read that attribute is considered "tightly > > > coupling". > > > > Is it unusual to use the Form Bean as a method of defining something > that > > > > contains properties for all of the fields that will be used across > pages > > > > (and thus across requests AND Actions) like in a Wizard interface? > > > > Although it may seem like our example code was tightly coupled, it > > > > really doesn't matter what happens with the forwards in between > actions. > > > You > > > > are right in assuming that we could be forwarding to another servlet > > > before > > > > forwarding back to another action. However, if we did this, we still > would > > > > not want the form bean re-populated from the request when entering any > > > > subsequent action. > > > > When forwarding to a JSP, however, this is a completely different > > > > matter. Because returning from a JSP will yield an entirely new > request; > > > and > > > > thus the whole problem disappears. > > > > Take this scenario as a loosely-coupled example of another place > > > > where this problem could arise: > > > > The user forwards to an action from a JSP. The Action populates the > > > > form bean. The Action forwards to a servlet, which does its own thing. > > > Then > > > > that servlet forwards to another servlet, which does yet another > thing. > > > Then > > > > a third non-Action servlet is forwarded to, which actually removes the > > > Form > > > > Bean from the session (for some unknown reason). When that servlet > > > forwards > > > > to another Action, the Action will re-create the removed Form Bean and > > > > re-populate it from the request. > > > > This is very loosely-coupled. In fact, the two actions don't care > > > > about one another at all. The problem is that a very unnatural thing > > > > happens; the Form Bean is recreated AND repopulated! Both of these > > > > behaviours are contrary to what the code is trying to do. > > > > It is true that actions do not know where they are going to or where > > > > they are coming from; they don't need to. But Struts should know if it > has > > > > processed the request parameters or not, so that it does not do the > same > > > > work over and over, and so that it does not override the Form Bean > > > > attributes set by servlets/Actions. > > > > Perhaps Struts should have a dirty marker that is placed in the > > > > request after Struts processes the request parameters, so that it does > not > > > > re-process them? It could set a request Attribute and the > ActionServlet > > > > could read this boolean value to see if the Form Bean has been > populated > > > > from the request parameters yet or not. Because some people already > have > > > > applications which rely on the current behaviour, it might also be a > good > > > > idea to have this dirty marker be activated/disactivated from the > Struts > > > > config file? > > > > Perhaps we are doing things completely incorrectly, but if we are, > > > > then what is the right way? Your suggestion of having our Actions > agreeing > > > > on retrieving the Form Bean from some other location would actually > make > > > our > > > > Actions very tightly coupled, whereas right now they are not. This > also > > > > bypasses Struts completely. What we are doing in the mean time is > sending > > > > our own values in the HTTPRequest from the JSP without using Struts > form > > > > elements, and setting the attributes of the Form Bean ourselves in the > > > > Action class -- thus bypassing Struts which would do it upon EVERY > > > > Action.perform() call. This bypasses Struts too, and we would like to > > > > actually use the Struts form elements in our JSPs; but if we do... we > run > > > > into the problem of Struts re-setting our Form Bean attributes on > every > > > > Action.perform() call. Is there anything we can do? > > > > > > > > Sincerely, > > > > > > > > Daryl and Terry. > > > > > > > > > > > > -----Original Message----- > > > > From: Martin Cooper [mailto:[EMAIL PROTECTED]] > > > > Sent: Sunday, April 21, 2002 1:45 AM > > > > To: Struts Developers List > > > > Subject: Re: ActionServlet re-populates form upon Actoin => Action > call > > > > > > > > > > > > What you are seeing is a natural consequence of the Servlet spec, and > in > > > > particular the behaviour of the RequestDispatcher. Here are some > points to > > > > consider: > > > > > > > > * When you forward a request, all of the request parameters are > preserved > > > > and presented to whatever processes the forwarded request. Therefore, > it > > > is > > > > natural that those original values be used to populate any form bean > > > > associated with a forwarded-to action, should the target of the > forward > > > > happen to be a Struts action. > > > > > > > > * A forward need not target a Struts action. It may go to a JSP page, > > > > another servlet in the web app, or something else. You may happen to > know > > > > that, for your application, the target is another Struts action, but > > > Struts > > > > cannot assume that. > > > > > > > > * A forwarded-to action does not know that it was forwarded to from > > > another > > > > action. It could have been forwarded to from a JSP page, a non-Struts > > > > servlet, or something else. Therefore, Struts cannot assume that the > form > > > > bean has already been populated by some prior action. > > > > > > > > It seems that you have some very specific assumptions built into your > app. > > > > In particular, your actions are very tightly coupled. For example, > your > > > > actions "know" that they are forwarding to another action, and > further, > > > they > > > > "know" the type and instance of the form bean that the other action > will > > > > use. This type of coupling is one of the things that Struts really > tries > > > > hard to avoid. > > > > > > > > If you really need this kind of tight coupling between your actions, > then > > > > you can have your actions "agree" on some other location from which > they > > > can > > > > obtain their form bean, rather than using the one that Struts will > pass to > > > > your execute() method. > > > > > > > > -- > > > > Martin Cooper > > > > > > > > > > > > ----- Original Message ----- > > > > From: "Terrence Xavier" <[EMAIL PROTECTED]> > > > > To: <[EMAIL PROTECTED]> > > > > Sent: Thursday, April 18, 2002 11:21 AM > > > > Subject: ActionServlet re-populates form upon Actoin => Action call > > > > > > > > > > > > > Dear Struts Developers, > > > > > > > > > > We have noticed some unexpected behavior with Struts. Basically, if > > > > > the HTTPRequest specifies attributes to modify in a struts form, > they > > > get > > > > > modified on EVERY call to the ActionServlet. An example of this is > as > > > > > follows. Say that we have a JSP that sets a form attribute, and then > we > > > > > submit to an Action class. From that Action, we modify the same form > > > > > attributes, and then forward to another Action. The problem we are > > > seeing > > > > is > > > > > that the form attributes get re-set upon entry into the second > Action, > > > > thus > > > > > overwriting our changed values in the form from the first Action. > > > > > The normal expected behaviour is that we can change the form > > > > > attributes in an Action, and then forward to another action and read > > > those > > > > > changed values. However, due to how the ActionServlet processes > > > > > HTTPRequests, those values will be replaced with the values > specified in > > > > the > > > > > HTTPRequest. Since the parameters in the HTTPRequest are read-only, > we > > > > > cannot override this functionality. > > > > > We have done extensive testing of this "bug" over the past few days. > > > > > We have written a simple project to demonstrate the issue, and have > > > tested > > > > > it with Struts 0.5, 1.0.2, and 1.1b1. Each of those versions of > Struts > > > > > functions the same with regard to this issue. > > > > > > > > > > Here is what is happening in more detail: > > > > > > > > > > The ActionServlet processes the HTTPRequest and populates the form > > > > > bean from the parameters in the HTTPRequest. This occurs before > > > > > instantiating the Action class to "perform". Thus, if we forward > from > > > > Action > > > > > to Action, when the same request is passed by the servlet engine, > the > > > form > > > > > bean gets populated twice -- before and after the first Action. So > form > > > > bean > > > > > values set within the Action that are also present in the > HTTPRequest > > > get > > > > > overridden with the values from the HTTPRequest. > > > > > Our simple project (attached to this e-mail) demonstrates this. > > > > > Here's the flow of that project: > > > > > > > > > > > > > > > JSP => Action1 => Action2 => etc... > > > > > | | | | | > > > > > V V V V V > > > > > set(x)=2 (x=2) set(x)=4 (x=2) get(x)=2 > > > > > > > > > > > > > > > In our project, whenever we enter and leave an action, we print out > > > > > a string indicating that we are entering or leaving the action. We > also > > > > have > > > > > print statements inside every getter and setter in the form bean > that > > > will > > > > > tell us whenever anything is retrieved or set in the form. This is > the > > > > > output we get from our application (with extra a couple comments to > help > > > > > explain what is going on): > > > > > > > > > > *********** startActionOne **************START > > > > > formAction : setFormAction() originalValue > > > > > *********** startActionOne **************END > > > > > +++++++++++ One.jsp +++++++++ > > > > > formAction : setFormAction() changedbyOneJSP <-- Struts sets > the > > > > form > > > > > bean attribute from JSP. > > > > > *********** ActionOne **************START > > > > > formAction : getFormAction() changedbyOneJSP > > > > > formAction : setFormAction() changedbyActionOne > > > > > *********** ActionOne **************END > > > > > formAction : setFormAction() changedbyOneJSP <-- Unexpected > > > > behavior > > > > > occurs here > > > > > *********** StartActionTwo **************START > > > > > formAction : setFormAction() changedbystartActionTwo > > > > > *********** StartActionTwo **************END > > > > > +++++++++++ Two.jsp +++++++++ getFormAction() = changedbyOneJSP > > > > > > > > > > > > > > > It is easy to see why this behaviour would be unexpected. After > > > > > explicitly setting the "formAction" attribute of the form in > ActionOne, > > > it > > > > > is re-set by Struts before ActionTwo is "performed". > > > > > > > > > > Given that this is how Struts functions, our questions are these: > > > > > > > > > > 1) We have work-arounds by using session request attributes, but we > > > > > would like to set form values in actions. How do we do this within > the > > > > > Struts framework and have them retain their values? > > > > > > > > > > 2) Since Struts seems to process the request twice, setting the form > > > > > attributes over and over again for each action that is forwarded to, > > > does > > > > it > > > > > make sense to change Struts so that it does not do the same work on > the > > > > same > > > > > HTTPRequest object more than once? > > > > > > > > > > 3) Is this well-known issue? > > > > > > > > > > We would appreciate any input you can offer. > > > > > > > > > > Sincerely, > > > > > > > > > > Daryl Beattie and Terrence Xavier > > > > > > > > > > P.S. The example code is configured to work with Struts 1.1b1 right > now. > > > > We > > > > > used the same project to test the other versions, but have since > changed > > > > it > > > > > to use 1.1b1. We did not include the jars in our zip file, so if you > > > want > > > > to > > > > > try it you will have to copy the Struts jars (and its dependent > jars) in > > > > the > > > > > WEB-INF/lib folder. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > -------------------------------------------------------------------------- > > > -- > > > > ---- > > > > > > > > > > > > > -- > > > > > To unsubscribe, e-mail: > > > > <mailto:[EMAIL PROTECTED]> > > > > > For additional commands, e-mail: > > > > <mailto:[EMAIL PROTECTED]> > > > > > > > > > > > > -- > > > > To unsubscribe, e-mail: > > > <mailto:[EMAIL PROTECTED]> > > > > For additional commands, e-mail: > > > <mailto:[EMAIL PROTECTED]> > > > > > > > > -- > > > > To unsubscribe, e-mail: > > > <mailto:[EMAIL PROTECTED]> > > > > For additional commands, e-mail: > > > <mailto:[EMAIL PROTECTED]> > > > > > > > > > -- > > > To unsubscribe, e-mail: > <mailto:[EMAIL PROTECTED]> > > > For additional commands, e-mail: > <mailto:[EMAIL PROTECTED]> > > > > > > > > > > > > -- > > To unsubscribe, e-mail: > <mailto:[EMAIL PROTECTED]> > > For additional commands, e-mail: > <mailto:[EMAIL PROTECTED]> > > > > > > > -- > To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> > For additional commands, e-mail: <mailto:[EMAIL PROTECTED]> > > -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>