You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by Cedric Dumoulin <ce...@lifl.fr> on 2002/07/18 15:22:17 UTC
Factorize "request dispatch" processing (in one single processActionForward(...))
Hi,
In order to solve some problems encountered with Tiles and multi
modules, I have tried to formalize what is the "workflow" of an incoming
request sent to an action.
Ideally, it should be (from a very high level point of view):
http://action.do
|
V
request preprocessing (populate formbean, validate, ...)
|
V
struts action call
|
V
request dispatch (usually to a view rendering page)
In Struts, the "request dispatch" block usually takes an ActionForward
as parameter and forward to requested URI. This is done in the
RequestProcessor.processActionForward(...) method.
Formalizing this workflow help to explain how Tiles fit in it. Tiles
are mainly rendering views. A tiles can be inserted by using its logical
names (the definition name) as URI in an actionForward, or anywhere a
path URI could takes place. Tiles insertion is done in the "request
dispatch" block: if the URI correspond to a Tiles, this Tiles is
inserted. Otherwise, normal Struts mechanism is used (forward to the URI).
Struts always follows this workflow, except in some cases ;-(. This
is where problems arise. Checking the struts-config.dtd file, I have
listed where a path URI could takes place, and then I have check the
associated "workflow":
* <action ...> ... <forward path="URI" ....>
o This is the general mechanism. It end by calling
RequestProcessor.processActionForward(...)
* <exception path="URI" ....>
o This also end by calling
RequestProcessor.processActionForward(...)
* <action forward="URI" ...>
o Dispatching is embedded in processForward(...),
o code: String uri = appConfig.getPrefix() + uri; doForward();
* <action include="URI" ....>
o Dispatching is embedded in processInclude(...),
o code: String uri = appConfig.getPrefix() + uri; doInclude();
* <action input="URI or forwardName" ...>
o Dispatching is embedded in processValidate(...)
o code: String uri = null;
if (appConfig.getControllerConfig().getInputForward()) {
ForwardConfig forward = mapping.findForward(input);
uri = RequestUtils.forwardURL(request, forward);
} else {
uri = appConfig.getPrefix() + input;
}
doForward(uri, request, response);
The point to note is that all paths are not process in the same way !
Paths in <forward ...> can be flagged as contextRelative, while path
from attribute input/forward/include can't (they are always module
relatives). Also, a forward used in attribute "input" doesn't take into
account the sendRedirect flag.
The attributes "forward" and "include" can only take URI, while "input"
can also takes an actionForward name.
Question: Do these different behaviors are voluntary, or just a
consequence of the growing code ?
What I would like to do is to factorize the way paths are processed in
one "request dispatch" block. This will help the integration of Tiles,
but also the integration of others framework providing rendering views.
Tiles, and others tools will subclass the RequestProcessor and override
the methods doing the "request dispatch".
Typically, Tiles interception should happen before the URI is modified
by concatenation of the module prefix. I can put some code everywhere,
but it will not be so nice, and not maintainable.
Ideally, factorization should be done in one single method (or two:
one forward, one include). For example, this can happen by calling
processActionForward(..., ActionForward ). This imply that the URI
string (from attributes include, forward, input) should be wrapped in an
ActionForward object. The advantage is that such URI can in a future
release be associated with the same properties than an actionForward,
and also that processing is the same for all.
An intermediate solution is to have 3 kinds of "request dispatch" blocks :
* processActionForward(..., ActionForward ):
o Same method as today. Called when we want to forward the
request according to actionForward content.
* doContextRelativeForward(String uri, request, response)
o Called when we want to do a forward to a context relative
uri. Method add module prefix to uri and do the forward.
* doContextRelativeInclude(...)
o Called when we want to do an include to a context relative
uri. Method add module prefix to uri and do the include
In this solution, the action's attribute "input" will end with a call to
processActionForward(...) or a call to doContextRelativeForward(...).
This solution avoid the extra creations of actionForward objects.
Please send me your comments asap, I experiment the second solution
and will be ready to commit it soon.
Cedric
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>