Ted -

I have a related question on the topic of reusing actions or DispatchAction.

I've been successfully using the Dispatch action in the development of an
application here, without yet implementing validation.  I'm using
DynaValidatorActionForm beans and extending action classes from
DispatchAction.  Now, in thinking of implementing validation, I see a
potential problem.  We will be using the XML Validator, with validation
executed by the controller.

Here is an example action mapping:

<action
  path="/FWMatDevRequestManage"
  type="ext.fwnike.client.material.action.FWMatDevManageDispatchAction"
  name="FWMatDevRequestForm"
  scope="request"
  parameter="method"
  input="/ext/fwnike/client/material/jsp/page/FWMatDevRequestEdit.jsp">
  <forward name="update" contextRelative="true"
path="fw.material.matdevrequest.update"/>
  <forward name="create" contextRelative="true"
path="/ext/fwnike/client/material/jsp/page/FWMatDevRequestEdit.jsp"/>
  <forward name="view" contextRelative="true"
path="fw.material.matdevrequest.view"/>
  <forward name="home" contextRelative="true"
path="/ext/fwnike/client/material/jsp/page/FWMatDevRequestHome.jsp"/>
</action>

As you can see, this action handles the CRUD functions, and while there is
only one "edit" JSP, separate forwards are used for Create and Update, since
there must be separate Tiles template definitions that use the edit.JSP (for
setting page titles/headlines, etc. for the appropriate page).

The issue I'm thinking comes when a validation error occurs, and the
controller routes the request back to the path specified by the "input"
parameter.  This seems to be a problem, because there are more than one
pages in the DispatchAction submitting form data, but only one "input"
parameter path.  So, there may be a validation error from the Create page,
in which case the Create page should be displayed again by the controller;
there may also be a validation error from the Update page, in which case the
Update page should be displayed again by the controller.  With only one
"input" parameter, how is this accomplished?

I hope that this description is clear; it seems like a pretty basic issue in
using the Dispatch action combined with the Validator.  I've looked through
the list, though, and didn't see this topic touched on.

Do you have any thoughts on this of possible approaches for this situation,
or are there standard approaches out there that I just haven't uncovered
yet?  Any assistance/advice is appreciated.


Thanks and regards,
Don Peterkofsky

*       From: Ted Husted 
*       Subject: Re: code reuse 
*       Date: Sun, 22 Jul 2001 11:54:30 -0700 

I would say that if you have one EJB for all these properties, then you
should have one ActionForm as well.

The trick to ActionForm reuse is the validation method. If the class is
used on more than one form, then validate() may need to address a
different set of properties. If you are using the ValidatorForm, it has
a "page" property. Each formset can have its own page name, and can
validate only the properties relevant to that formset. Otherwise,
validate() is passed the ActionMapping, and you can use that to
determine your own form sets. Some developers also use hidden fields for
the same purpose.  

Of course, if only one form is used for data-entry, validating more than
one form may not be an issue.

Once you have an ActionForm that you can use on more than one form, you
can also use the same Action to handle them all. Since Actions are
multithreaded and cached by the framework, fewer Actions can mean a
better deployment. 

I'm often tempted to try designing an application around a single 
ActionForm and Action. This may make for a more efficient Struts 
application, but may also lead to maintenance issues.

In general, I tend to design my applications around "packages" or
modules. The package may offer several operations and JSP views, but use
only one Action and ActionForm for them all.

My favorite way to use an Action with several operations is to use a
separate ActionMapping for each. An easy way to tell one mapping during
processing from another is to use the parameter property to give each a
logical name. 

<action 
parameter="select"
path="/donor/Search"
type="org.wxxi.gavel.donor.http.Client"
name="donorForm"
scope="request"
validate="false">
<forward 
    name="continue"  
    path="/WEB-INF/pages/donor/Result.jsp"/> 
</action>

<action 
parameter="select"
path="/donor/View"
type="org.wxxi.gavel.donor.http.Client"
name="donorForm"
scope="request"
validate="false">
<forward 
    name="continue"  
    path="/WEB-INF/pages/donor/View.jsp"/>
</action>

In perform() or validate(), you can call mapping.getParameter(), and
call the appropriate operation.

The parameter property was originally introduced to support the optional
DispatchAction class. This uses reflection to call a different perform()
method for each operation. This is a nifty feature, and I do something 
similar by subclassing Actions and giving the ancestors a utility 
method to handle stadnard operators, across a package or even the 
entire application. 

The current DispatchAction expects the Action to be called using a
syntax like 

<http://localhost:8080/myapp/saveSubscription.do?method=update> 

where "method" is set as the parameter property.

The Action then dispatches this call to a public method with the
signature 

public ActionForward update(ActionMapping mapping, ActionForm form,
     HttpServletRequest request, HttpServletResponse response) throws
IOException,
     ServletException 

As soon as I find a good chance to use DispatchAction, I may try an
alternative that uses the parameter for the operation name, so the
syntax would be 

<http://localhost:8080/myapp/updateSubscription.do>

with "update" given as as the parameter. (I prefer minimize reliance on
query strings and hidden fields.)

Of course, both the ActionForm and the Action are straight-forward Java
classes, and developers are encouraged to create ancestor classes for
common behaviours when applicable. Subclassing the ActionServlet to
reuse code is another common strategy.

Speaking of subclassing, you can also often reuse an Action to handle 
various ActionForms throughout your application. For example, a single
one-line InputAction can be used to seed all of your input forms: 

 return (new ActionForward(mapping.getInput()));

You can InputAction from any mapping, using any ActionForm, and the 
result will be a blank form, ready for data entry. Which ActionForm
is instantiated and what page is used for input is controlled by the 
mapping, not the Action itself.


-- Ted Husted, Husted dot Com, Fairport NY USA.
-- Custom Software ~ Technical Services.
-- Tel 716 737-3463.
-- <http://www.husted.com/about/struts/>

> Steve LeClair wrote:
> 
> Our firm is has been using the struts framework to build our
> application demos. Now that we are shifting into a development cycle
> for a production release, we'd like to know more about how to build
> the struts side of our codebase with reuse in mind.
> 
> Has anyone collected threads on reuse strategies?
> 
> For instance, in the demo we display/update coporate Address
> information on the Order form,  on the Account Maintenance form and
> also in a popup (independent) form. Now it seems silly to have three
> sets of form/action classes to manage the same data (at least we only
> use one EJB ;>)
> 
> Advice?
> 
> Thanks...Steve






--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to