struts-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ted Husted <hus...@apache.org>
Subject [LONG] Re: action-mapping: why must the action-Attributepath be equivalent to the name of the jsp?
Date Wed, 01 Aug 2001 12:01:02 GMT
John Yu wrote:
> I'm wondering if it makes sense to extend Struts' mapping architecture
> so that it will also look into a 'magic' url parameter and dispatch
> accordingly.
> 
> For example, if the URL is
> 
>      MyAction.do?subAction=Create
> 
> the ActionServlet will dispatch the request to the MyActionCreate
> class given the following (enhanced) action mapping.
> 
>   <action path="MyAction" subAction="Create" type="MyActionCreate"
> .../>


Actions can forward to other ActionMappings, if the mappings are exposed
as ActionForwards. If that's something you would like to do, you can use 
a generic dispatcher that would look for the "subaction" parameter and 
return the appropriate forward to another mapping.

Here's an example perform() that can forward anywhere given
"/do/Dispatch?forward=forwardName".

  // -- Locals
  ActionForward thisForward = null;
  String wantForward = null;

  // -- Check check request for forward
  wantForward = request.getParameter("forward");

  // -- If found, consult mappings
  if (wantForward!=null)
      thisForward = mapping.findForward(wantForward);

  // -- If anything not found, dispatch error
  if (thisForward==null) {
      thisForward = mapping.findForward("error");
      ActionErrors errors = new ActionErrors();
      errors.add(ActionErrors.GLOBAL_ERROR,
          new ActionError("action.missing.parameter"));
      saveErrors(request, errors);
  }

  return thisForward;

Here's a simple "Hello World" action to test it:

    response.setContentType("text/plain");
    PrintWriter writer = response.getWriter();
    writer.println("Hello from: " + mapping.getPath());
    return(null);

And some sample mappings:

    <!-- Dispatcher action mapping -->
    <action 
        path="/Dispatch"
        type="ext.http.DispatchForward"
        scope="request"
        validate="false">
       <forward
            name="test1"
            path="/do/Test1"/>
       <forward 
            name="test2"  
            path="/do/Test2"/>
    </action>

    <action 
        path="/Test1"
        type="ext.http.Test1"
        scope="request"
        validate="false">
    </action>

    <action 
        path="/Test2"
        type="ext.http.Test1"
        scope="request"
        validate="false">
    </action>

If you ask for "do/Dispatch?task=test1" you get "Hello from test1" if
you open "do/Dispatch?task=test2" you get "Hello from test2". (Note that
an Action knows which path is used to call it, which is another way you
can have Actions do different things based on the mapping context.) 

I only just wrote this, and it seems OK, but be warned that it is alpha
code ;o)

A couple of things to keep in mind: 

+ You never really call an Action. You reference an ActionMapping, and
the Controller calls the Action from that. 

+ The ActionForms are populated from the request when the controller
invokes the Action for a mapping. So if you forward the request to
another mapping, it would populate the form for that mapping from the
forwarded request. 

+ Actions are not bound to ActionForms. The form is bound by the 
ActionMapping, and an Action can be used in any number of mappings.

+ Many times developers use the same or related names for an Action and
the path to an ActionMapping. That is only a convenience. In Struts, you
can only specify a "logical" path to an ActionMapping. What is behind
that mapping is determined by the configuration file, and therefore 
belongs to the controller layer. 

Meanwhile ... a similar thing to the DispatchForward class given above 
can be done using the optional DispatchAction class in Struts 1.0
(org.apache.struts.actions.DispatchAction). Here you can create
alternate "perform" methods in a single action, and call one or the
another in the request. So you could have 

    public ActionForward retrieve(ActionMapping mapping, ...
    public ActionForward update(ActionMapping mapping, ...

and then call one or the other using "myDispatchAction?method=retrieve"
or "myDispatchAction?method=update". See the Struts JavaDoc for details.

Very neat, really.

-Ted.

Mime
View raw message