You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by Brian Moseley <bc...@covalent.net> on 2002/12/11 01:33:13 UTC

dynamic input paths

i'm using struts 1.1b2 to perform a simple validation on an action form. 
it works great, except:

when validation fails, i need to specify an additional request parameter 
for the input path, as the input page requires that parameter to exist. 
unfortunately, i get a "configuration frozen" error when i try to modify 
the input path in the action form's validate method.

i've considered but rejected using a session attribute instead of a 
request parameter for this particular piece of data. other than that, is 
there a solution that i'm missing?

thanks!


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


Re: modifying the mapping input path during validation

Posted by Brian Moseley <bc...@covalent.net>.
Erik Hatcher wrote:

 > Yes, but only if you tell your action mapping the form bean associated
 > with it, and from what you showed above, you don't.

yep, that was silly eh? i hadn't even considered that the form could be
shared across actions like that. i was certain that you guys would have
already solved this problem.. :) thanks again!




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


Re: modifying the mapping input path during validation

Posted by Erik Hatcher <ja...@ehatchersolutions.com>.
I'm getting more than I bargained for here with the whole tiles aspect, 
so I might be done helping now that the complexity has gone up, but just 
a bit more here....

Brian Moseley wrote:
>       <action path="/admin/role/EditFormPrepare"
> 
> type="net.covalent.spider.ui.action.portlet.admin.role.EditFormPrepareAction">
>       </action>

You need name="..." for this action mapping.  That should solve the 
issue, it seems.

> all of these forwards execute in the context of the same 
> RequestProcessor tho, right? so presumably the EditForm instance gets 
> passed all the way down the forward chain through the tiles controller 
> invocation mechanism to EditFormPrepareAction?

Yes, but only if you tell your action mapping the form bean associated 
with it, and from what you showed above, you don't.

> is this an instance of "evil action chaining"? if so, what actually is 
> the evil?

It was a joke.  I dig action chaining.  Others do not.  See previous 
thread a few days ago.

> yeah, there's no "cleaner" way that i can think of. my team is 
> especially wary of using the session scope for managing page flow, so 
> rewriting the forward path in the action is the least offensive hack :)

Or keeping the form bean around and using it.  And I agree with the 
session scope page flow comment - its not necessary in my experience.

	Erik



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


Re: modifying the mapping input path during validation

Posted by Brian Moseley <bc...@covalent.net>.
Erik Hatcher wrote:

> Yes, it should be.  Do you have the form name listed on that action? 
> Let's see your action mappings for the prepare and edit actions.

       <action path="/admin/role/EditFormPrepare"
 
type="net.covalent.spider.ui.action.portlet.admin.role.EditFormPrepareAction">
       </action>

       <action path="/admin/role/Edit"
 
type="net.covalent.spider.ui.action.portlet.admin.role.EditAction"
               name="EditRoleForm"
               scope="request"
               input="/Home.do?id=104">
         <forward name="cancel" path="/Home.do?id=103" redirect="true"/>
         <forward name="reset" path="/Home.do?id=104"/>
         <forward name="failure" path="/Home.do?id=104"/>
         <forward name="success" path="/Home.do?id=103"/>
       </action>

> The form bean itself is null... hmmm???  strange - only if you've not 
> specified it on the action mapping is my guess.

aha! looking at this mapping clears up at least part of the mystery...

the input path is "/Home.do?id=104". HomeAction actually forwards to a 
jsp with a bunch of tiles in it. Edit.jsp is one of those tiles, and its 
controlling action is EditFormPrepareAction.

this means that when EditForm fails validation, i have this forward chain:

EditForm --> HomeAction ---> Home.jsp ---> (tiles controller mechanism 
invokes EditFormPrepareAction) ---> Edit.jsp.

all of these forwards execute in the context of the same 
RequestProcessor tho, right? so presumably the EditForm instance gets 
passed all the way down the forward chain through the tiles controller 
invocation mechanism to EditFormPrepareAction?

is this an instance of "evil action chaining"? if so, what actually is 
the evil?

> Oh, there are always around things!  :)  Putting things in request or 
> session scope work, depending on whether you are doing a redirect.  Or 
> the evil action chaining keeping things available for you in a later 
> action.  And I'm sure some other tricks too.

yeah, there's no "cleaner" way that i can think of. my team is 
especially wary of using the session scope for managing page flow, so 
rewriting the forward path in the action is the least offensive hack :)




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


Re: modifying the mapping input path during validation

Posted by Ted Husted <hu...@apache.org>.
12/17/2002 2:31:52 PM, Erik Hatcher <jakarta-
struts@ehatchersolutions.com> wrote:
>Or  the evil action chaining keeping things available for you in 
>a later action.  

IMHO, Action chaining is linking three or more Actions together. 
(e.g., three points determine a chaine :0) Simply forwarding from 
one Action to another, so the second can select the page and 
complete the response, is an ordinary and expected use of the 
framework. 

The "evil" part is when people start using the Action objects as 
an API and want to pass (new) parameters from one Action to 
another, either by changing the properties on the ActionForm or by 
creating a new query string on the fly. The danger here is that 
the Action *classes* become coupled and start looking like a mess 
of "GOTO"s. 

While there could be exceptions, this usually indicates that there 
is not sufficient separation between the Action classes and the 
business tier. Why? Because if I have a decent business facade, I 
shouldn't have to kludge-around with setting new properties on an 
ActionForm or as a request parameter. I should be able to code 
directly to the business facade. 

Now, none of this speaks to the current thread, I just wanted to 
chime in about the Action Chaining. IMHO, Erik doesn't practice 
Action Chaining, as the term was originally used, he simply links 
from one Action to another, which is an expected practice. 

-Ted.




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


Re: modifying the mapping input path during validation

Posted by Erik Hatcher <ja...@ehatchersolutions.com>.
Brian Moseley wrote:
> because the form fails validation, the RequestProcessor immediately 
> forwards to the form's input page instead of handing off to the action 
> associated with the form. so no, i can't do it in that action.
> 
> there is a "prepare" action for the input page as well:
> 
>   flow a: EditFormPrepareAction ---> Edit.jsp
>   flow b: Edit.jsp ---> EditForm ---> EditAction
> 
> during flow b, if EditForm fails to validate, the request is forwarded 
> back to flow a.

Ok, thanks for the details.  It makes sense now.

So, how about changing EditFormPrepareAction to first look for the 
object id on the form bean that is being passed in, otherwise pull it 
from the request?  Then you'd be able to come in with ?id=<whatever> or 
through a forwarded validation error.

Oh, but I see you've tried that...

> i expected that, after EditForm fails to validate, the form object 
> passed into EditFormPrepareAction would be the same instance of EditForm 
> that failed validation (where the required bit of data is available as 
> an attribute).

Yes, it should be.  Do you have the form name listed on that action? 
Let's see your action mappings for the prepare and edit actions.

> in fact, the form object that's passed into the prepare action is null. 
> i don't know why.

The form bean itself is null... hmmm???  strange - only if you've not 
specified it on the action mapping is my guess.

>> Sometimes we "hack" a request parameter in to the forward from the 
>> action by creating a new ActionForward based on the path of an 
>> existing one...
>>
>>     return new ActionForward(mapping.findForward("success").getPath() 
>> + "?id=" + id);
>>
>> (hopefully no typos there, but you get the idea).  No need to do 
>> session scope stuff to make this happen.
> 
> 
> yep, when i need to change a forward path inside an action, i do almost 
> exactly this. it may be a hack, but i don't see any way around it.

Oh, there are always around things!  :)  Putting things in request or 
session scope work, depending on whether you are doing a redirect.  Or 
the evil action chaining keeping things available for you in a later 
action.  And I'm sure some other tricks too.

> i apologize for being imprecise in the original post. the prepare action 
> is the component that requires the request parameter. it then sets a 
> request attribute, which is used by the jsp. so i'm already following 
> that bit of advice :)

I'd modify the code so that a request parameter is optional if it can be 
gotten another way.

	Erik


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


Re: modifying the mapping input path during validation

Posted by Brian Moseley <bc...@covalent.net>.
Erik Hatcher wrote:
> I'm not following why you need to do this in the form bean rather than 
> just dealing with this in the action.  The action class is designed for 
> flexible routing out of it, so the capability is already there as you've 
> already mentioned using.

because the form fails validation, the RequestProcessor immediately 
forwards to the form's input page instead of handing off to the action 
associated with the form. so no, i can't do it in that action.

there is a "prepare" action for the input page as well:

   flow a: EditFormPrepareAction ---> Edit.jsp
   flow b: Edit.jsp ---> EditForm ---> EditAction

during flow b, if EditForm fails to validate, the request is forwarded 
back to flow a.

i expected that, after EditForm fails to validate, the form object 
passed into EditFormPrepareAction would be the same instance of EditForm 
that failed validation (where the required bit of data is available as 
an attribute).

in fact, the form object that's passed into the prepare action is null. 
i don't know why.

> Sometimes we "hack" a request parameter in to the forward from the 
> action by creating a new ActionForward based on the path of an existing 
> one...
> 
>     return new ActionForward(mapping.findForward("success").getPath() + 
> "?id=" + id);
> 
> (hopefully no typos there, but you get the idea).  No need to do session 
> scope stuff to make this happen.

yep, when i need to change a forward path inside an action, i do almost 
exactly this. it may be a hack, but i don't see any way around it.

> So what you're trying to do is already possible, although even the above 
> is a 'hack' I think and while it comes in handy in a pinch it'd be nicer 
> to craft it so that the next page or action can deal with a request 
> scoped attribute rather than a parameter.

i apologize for being imprecise in the original post. the prepare action 
is the component that requires the request parameter. it then sets a 
request attribute, which is used by the jsp. so i'm already following 
that bit of advice :)


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


Re: modifying the mapping input path during validation

Posted by Erik Hatcher <ja...@ehatchersolutions.com>.
I'm not following why you need to do this in the form bean rather than 
just dealing with this in the action.  The action class is designed for 
flexible routing out of it, so the capability is already there as you've 
already mentioned using.

Sometimes we "hack" a request parameter in to the forward from the 
action by creating a new ActionForward based on the path of an existing 
one...

	return new ActionForward(mapping.findForward("success").getPath() + 
"?id=" + id);

(hopefully no typos there, but you get the idea).  No need to do session 
scope stuff to make this happen.

So what you're trying to do is already possible, although even the above 
is a 'hack' I think and while it comes in handy in a pinch it'd be nicer 
to craft it so that the next page or action can deal with a request 
scoped attribute rather than a parameter.

	Erik


Brian Moseley wrote:
> 
> any comments on the problem i've outlined below?
> 
> i realize that it's not clean to give a form bean any amount of control 
> logic (which is what i want to do by allowing it to manipulate the input 
> path). i'd prefer to avoid this if possible.
> 
> one thought is that RequestProcessor.process could offer a "post 
> validation" hook that would allow the input path to be specified by an 
> application component. but which component? neither actions or forms 
> make sense here.
> 
> another thought: form definitions in struts-config optionally specify 
> sprintf-like format strings which are used by the 
> mapping/forward/whatever to dynamically generate paths.
> 
> once again, the requirement i have to live with is that my form's input 
> page requires a particular request parameter to be set. it's just a form 
> for modifying the attributes of a model object, and the request 
> parameter is simply the object's unique id.
> 
> this is clearly a common design pattern; how do other people solve the 
> problem of providing a needed request parameter to an action form's 
> input after a failed validation?
> 
> Brian Moseley wrote:
> 
>>
>> i sent the below message to struts-user a couple of days ago. since 
>> that time i tried to address the problem by creating a subclass of 
>> RequestProcessor and overriding the process method. didn't work.
>>
>> i figured i could make an "unfrozen clone" of the mapping to pass into 
>> processValidate, which would allow my form to set the input path 
>> inside its validate method. unfortunately, there was no clean way to 
>> do this; i didn't want to cut and paste processValidate into my 
>> subclass, and there is no hook within process to allow a subclass to 
>> step in and create the mapping clone.
>>
>> i wound up having the form set a session attribute which the action 
>> then gets and removes. a grotesque solution to be sure, but the only 
>> apparent alternative was worse.
>>
>> so the question i put to you folks is: how must struts change to allow 
>> me to modify the mapping's input path inside the form's validate 
>> method? or is there some existing solution that i'm completely missing?
>>
>> thanks!
>>
>> Brian Moseley wrote:
>>
>>> i'm using struts 1.1b2 to perform a simple validation on an action 
>>> form. it works great, except:
>>>
>>> when validation fails, i need to specify an additional request 
>>> parameter for the input path, as the input page requires that 
>>> parameter to exist. unfortunately, i get a "configuration frozen" 
>>> error when i try to modify the input path in the action form's 
>>> validate method.
>>>
>>> i've considered but rejected using a session attribute instead of a 
>>> request parameter for this particular piece of data. other than that, 
>>> is there a solution that i'm missing?
>>>
>>> thanks!
>>>
>>
>>
>>
> 
> 
> 
> 
> --
> 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>


Re: modifying the mapping input path during validation

Posted by Brian Moseley <bc...@covalent.net>.
Ted Husted wrote:
 > My first suggestion would be try not to think in terms of request
 > parameters and try to think in terms of ActionForm properties.
 > Generally, all the request parameters should be represented as
 > ActionForm properties. Struts will then take care of automatically
 > populating the properties.
 >
 > My second suggestion would be to try and put gory details like id=
 > 104 behind ActionForward. Instead creating an ActionForward by
 > appending the parameter, you can call the forward by name. I don't
 > know what 104 does, but you could have the equivalent of
 >
 > <forward name="home104" path:/home.do?id=104"/>
 >
 > Where home104 is a descriptive name rather than an arbitrary
 > identifier.
 >
 > My third suggestion would be to use an ActionMapping for the input
 > property rather than a presentation page. Ideally, all pages
 > should be behind ActionMapping handlers. If you need to apply some
 > post-validation logic or seed any properties (!parameters) on the
 > ActionForm, you can do that here.

several fine suggestions; thanks very much for the feedback. my struts
work is much more sophisticated now that i've started asking questions
of the experts :)



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


Re: modifying the mapping input path during validation

Posted by Ted Husted <hu...@apache.org>.
My first suggestion would be try not to think in terms of request 
parameters and try to think in terms of ActionForm properties. 
Generally, all the request parameters should be represented as 
ActionForm properties. Struts will then take care of automatically 
populating the properties. 

My second suggestion would be to try and put gory details like id=
104 behind ActionForward. Instead creating an ActionForward by 
appending the parameter, you can call the forward by name. I don't 
know what 104 does, but you could have the equivalent of 

<forward name="home104" path:/home.do?id=104"/>

Where home104 is a descriptive name rather than an arbitrary 
identifier. 

My third suggestion would be to use an ActionMapping for the input 
property rather than a presentation page. Ideally, all pages 
should be behind ActionMapping handlers. If you need to apply some 
post-validation logic or seed any properties (!parameters) on the 
ActionForm, you can do that here. 

-Ted.

12/17/2002 1:10:28 PM, Brian Moseley <bc...@covalent.net> wrote:

>
>any comments on the problem i've outlined below?
>
>i realize that it's not clean to give a form bean any amount of 
control 
>logic (which is what i want to do by allowing it to manipulate 
the input 
>path). i'd prefer to avoid this if possible.
>
>one thought is that RequestProcessor.process could offer a "post 
>validation" hook that would allow the input path to be specified 
by an 
>application component. but which component? neither actions or 
forms 
>make sense here.
>
>another thought: form definitions in struts-config optionally 
specify 
>sprintf-like format strings which are used by the 
>mapping/forward/whatever to dynamically generate paths.
>
>once again, the requirement i have to live with is that my form's 
input 
>page requires a particular request parameter to be set. it's just 
a form 
>for modifying the attributes of a model object, and the request 
>parameter is simply the object's unique id.
>
>this is clearly a common design pattern; how do other people 
solve the 
>problem of providing a needed request parameter to an action 
form's 
>input after a failed validation?
>
>Brian Moseley wrote:
>> 
>> i sent the below message to struts-user a couple of days ago. 
since that 
>> time i tried to address the problem by creating a subclass of 
>> RequestProcessor and overriding the process method. didn't 
work.
>> 
>> i figured i could make an "unfrozen clone" of the mapping to 
pass into 
>> processValidate, which would allow my form to set the input 
path inside 
>> its validate method. unfortunately, there was no clean way to 
do this; i 
>> didn't want to cut and paste processValidate into my subclass, 
and there 
>> is no hook within process to allow a subclass to step in and 
create the 
>> mapping clone.
>> 
>> i wound up having the form set a session attribute which the 
action then 
>> gets and removes. a grotesque solution to be sure, but the only 
apparent 
>> alternative was worse.
>> 
>> so the question i put to you folks is: how must struts change 
to allow 
>> me to modify the mapping's input path inside the form's 
validate method? 
>> or is there some existing solution that i'm completely missing?
>> 
>> thanks!
>> 
>> Brian Moseley wrote:
>> 
>>> i'm using struts 1.1b2 to perform a simple validation on an 
action 
>>> form. it works great, except:
>>>
>>> when validation fails, i need to specify an additional request 
>>> parameter for the input path, as the input page requires that 
>>> parameter to exist. unfortunately, i get a "configuration 
frozen" 
>>> error when i try to modify the input path in the action form's 
>>> validate method.
>>>
>>> i've considered but rejected using a session attribute instead 
of a 
>>> request parameter for this particular piece of data. other 
than that, 
>>> is there a solution that i'm missing?
>>>
>>> thanks!
>>>
>> 
>> 
>> 
>
>
>
>
>--
>To unsubscribe, e-mail:   <mailto:struts-dev-
unsubscribe@jakarta.apache.org>
>For additional commands, e-mail: <mailto:struts-dev-
help@jakarta.apache.org>
>
>




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


Re: modifying the mapping input path during validation

Posted by Brian Moseley <bc...@covalent.net>.
any comments on the problem i've outlined below?

i realize that it's not clean to give a form bean any amount of control 
logic (which is what i want to do by allowing it to manipulate the input 
path). i'd prefer to avoid this if possible.

one thought is that RequestProcessor.process could offer a "post 
validation" hook that would allow the input path to be specified by an 
application component. but which component? neither actions or forms 
make sense here.

another thought: form definitions in struts-config optionally specify 
sprintf-like format strings which are used by the 
mapping/forward/whatever to dynamically generate paths.

once again, the requirement i have to live with is that my form's input 
page requires a particular request parameter to be set. it's just a form 
for modifying the attributes of a model object, and the request 
parameter is simply the object's unique id.

this is clearly a common design pattern; how do other people solve the 
problem of providing a needed request parameter to an action form's 
input after a failed validation?

Brian Moseley wrote:
> 
> i sent the below message to struts-user a couple of days ago. since that 
> time i tried to address the problem by creating a subclass of 
> RequestProcessor and overriding the process method. didn't work.
> 
> i figured i could make an "unfrozen clone" of the mapping to pass into 
> processValidate, which would allow my form to set the input path inside 
> its validate method. unfortunately, there was no clean way to do this; i 
> didn't want to cut and paste processValidate into my subclass, and there 
> is no hook within process to allow a subclass to step in and create the 
> mapping clone.
> 
> i wound up having the form set a session attribute which the action then 
> gets and removes. a grotesque solution to be sure, but the only apparent 
> alternative was worse.
> 
> so the question i put to you folks is: how must struts change to allow 
> me to modify the mapping's input path inside the form's validate method? 
> or is there some existing solution that i'm completely missing?
> 
> thanks!
> 
> Brian Moseley wrote:
> 
>> i'm using struts 1.1b2 to perform a simple validation on an action 
>> form. it works great, except:
>>
>> when validation fails, i need to specify an additional request 
>> parameter for the input path, as the input page requires that 
>> parameter to exist. unfortunately, i get a "configuration frozen" 
>> error when i try to modify the input path in the action form's 
>> validate method.
>>
>> i've considered but rejected using a session attribute instead of a 
>> request parameter for this particular piece of data. other than that, 
>> is there a solution that i'm missing?
>>
>> thanks!
>>
> 
> 
> 




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


modifying the mapping input path during validation

Posted by Brian Moseley <bc...@covalent.net>.
i sent the below message to struts-user a couple of days ago. since that 
time i tried to address the problem by creating a subclass of 
RequestProcessor and overriding the process method. didn't work.

i figured i could make an "unfrozen clone" of the mapping to pass into 
processValidate, which would allow my form to set the input path inside 
its validate method. unfortunately, there was no clean way to do this; i 
didn't want to cut and paste processValidate into my subclass, and there 
is no hook within process to allow a subclass to step in and create the 
mapping clone.

i wound up having the form set a session attribute which the action then 
gets and removes. a grotesque solution to be sure, but the only apparent 
alternative was worse.

so the question i put to you folks is: how must struts change to allow 
me to modify the mapping's input path inside the form's validate method? 
or is there some existing solution that i'm completely missing?

thanks!

Brian Moseley wrote:
> i'm using struts 1.1b2 to perform a simple validation on an action form. 
> it works great, except:
> 
> when validation fails, i need to specify an additional request parameter 
> for the input path, as the input page requires that parameter to exist. 
> unfortunately, i get a "configuration frozen" error when i try to modify 
> the input path in the action form's validate method.
> 
> i've considered but rejected using a session attribute instead of a 
> request parameter for this particular piece of data. other than that, is 
> there a solution that i'm missing?
> 
> thanks!
> 




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