You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by Terrence Xavier <TX...@insystems.com> on 2002/04/18 20:21:39 UTC

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.



Re: ActionServlet re-populates form upon Actoin => Action call

Posted by Martin Cooper <ma...@tumbleweed.com>.
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" <TX...@insystems.com>
To: <st...@jakarta.apache.org>
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:
<ma...@jakarta.apache.org>
> For additional commands, e-mail:
<ma...@jakarta.apache.org>


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>