struts-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Craig R. McClanahan" <>
Subject Re: FW: Does struts provide hooks for app-specific initialization?
Date Wed, 21 Jun 2000 21:35:27 GMT
David Chisholm wrote:

> [snip]
> > > 2.  Request pre-processing
> > >
> > > Is there a central point in struts where I can examine and modify all
> > > requests before they are delegated to an Action?
> > >
> > > I use request pre-processing to perform common actions such as
> > validating
> > > sessions and parsing out cross site scripting special characters from
> > > requests.  The request pre-processor class is configurable by the
> > > application just as the app-specific initialization class is.
> > >
> >
> > The processing logic to handle a request is performed in the
> > process() method of
> > ActionServlet, which is mostly a bunch of calls to other methods
> > that do the
> > more detailed processing.  You can again subclass ActionServlet,
> > and override
> > whichever particular processing method makes sense for what you
> > are trying to
> > do.  In this scenario, since you're actually modifying the behavior of
> > ActionServlet, you would take the "override init()" approach to
> > configuring it
> > as well, in order to add the dynamic class loading of your
> > pre-processor class.
> >
> > I'd be interested in your thoughts about some more general purpose
> > "preprocessing" hook that could get called ahead of the remaining
> > methods in the
> > processing chain.
> >
> Well, what I had done was to create an interface with one primary method:
>   public Boolean process(HttpServletRequest request) throws
> RequestPreprocessorException;
> If, for whatever reason, the preprocessor throws a
> RequestPreprocessorException, then the exception contains the WebPage
> (equivalent of ActionForward) to which the request will be forwarded or
> redirected.
> The Boolean return value indicates whether the request should be forwarded
> or redirected.  This applies to the WebPage in the
> RequestPreprocessorException as well as the WebPage returned by an Action.
> The WebPage class contains a redirect property too, but the value returned
> above will override it.  (I know this is a little confusing, and I plan to
> make it simpler.)

If you were using Struts as the basis, you might just return an ActionForward
from the preprocessor instead of a boolean.  Then you could implement something
like this, for example:

    protected void processActionInstance(...) ... {

        RequestPreprocessor preprocessor = ... find the right one ...
        ActionForward forward = preprossor.process(...);
        if (forward == null)
            ... do the forward or redirect trick ...


so that your preprocessor would return null if everything is fine (go on and
call the action), or a non-null ActionForward that says where to go and how to
get there.

> Another feature that I need to add to the request pre-processor is the
> ability to change the request and response objects.  Our application can
> manage it's own clustered environment, but to do that, it needs to wrap the
> servlet container's request and response objects with our own versions
> before the request and response objects are passed to any Actions.  This
> will also allow us to filter out special characters in the request before
> sending the request to an Action.

One difficulty you are going to have with this approach is a restriction in the
servlet API spec -- when you finally call RequestDispatcher.forward(), the
request and response objects you pass as parameters have to be the original ones
-- you cannot wrap them at this point.

An alternative to consider would be to copy all the request parameters you want
into request attributes, doing whatever filtering and replacement that you
need.  Then you can go ahead and call the action classes with the original
request and response arguments, with no difficulties.

Another alternative if you're using struts - if you are using an ActionForm bean
associated with your actions, the controller will have copied the matching
parameters into corresponding properties for you.  You can easily modify the
form bean properties, since you have both getters and setters available.

> Finally, pre-processors can be chained together using inheritance and
> calling super.process(request).
> Are these the kinds of ideas your interested in?

This is an interesting idea, but I'm a little hesitant about implementing it
within Struts.

The reason for this is that the entire topic of "request filtering" is currently
being discussed for the Servlet API version 2.3 spec (should be out for public
review before too much longer :-).  The idea will be that you can define some
sort of chain for pre-processing and post-processing requests around the servlet
itself, and it will be portable across servlet containers (because it will be
part of the spec).

I know it doesn't help your immediate need very much, but this particular
problem is one I'd like to wait and let the standards process deal with, instead
of trying to do something application specific, and limited to what a servlet
itself can do.

> > >
> > > 3.  Page parameterization
> > >
> > > Is there any way to declare output page parameters?
> > >
> > > In the applications that I'm working with, many of the pages are
> > > inter-changeable between different workflows, and we make each page
> > > independent of other pages and actions.
> > >
> > > A typical action that a page invokes is 'next', and it's up to
> > the 'next'
> > > action to figure out what exactly to do.  The 'next' action is
> > actually a
> > > composite Action that searches for the next Action in the
> > workflow, executes
> > > it, and returns that Action's jsp page.
> > >
> > > To make this work, pages have to declare what their output is, and this
> > > allows the 'next' action to forward that output to the next page.
> > >
> > > Ideally, pages would also declare what beans that they require
> > and actions
> > > would declare what parameters they require and what beans they
> > output.  Then
> > > we could perform static analysis of the configuration files to find
> > > mis-matches between actions and pages, but that's another to-do
> > item on my
> > > list.
> > >
> > > So does anyone have some information/ideas about how to handle
> > these issues
> > > with struts?
> > >
> >
> > Actions do declare what ActionForm bean they use (if any), and support was
> > recently added for ValidatingActionForm beans -- the controller
> > servlet will
> > call the validate() method and return to the original entry form
> > if it detects
> > any errors.
> >
> This is a nice feature.
> > For the action classes themselves, the concept of looking up the
> > next" page to
> > be displayed (i.e. the next action in a workflow) by a logical
> > name was added.
> > The default Struts implementation lets you preconfigure lookup
> > tables of either
> > global logical names, or local names that are specific to this action (or
> > both).  The example app's LogonAction uses this technique to
> > forward to a page
> > with logical name "success", for example, after an authenticated
> > logon.  The
> > fact that this page is named "/mainMenu.jsp" is a configuration parameter.
> >
> Understood.  This is what I do except that an action only has a single
> logical page.
> > Within a page, it is sometimes useful to be able to reference other pages
> > directly (because you're only manipulating the view, not changing
> > the state of
> > the system -- for the latter, you should still go through an
> > action that uses
> > the logical mapping described in the previous paragraph).  An
> > example would be
> > the "Next" and "Previous" buttons of a multi-page report, like
> > the results of a
> > search engine lookup.
> >
> This is where the struts framework and mine differ.  I don't allow pages to
> be accessed directly.  The requests have to be funneled through the action
> servlet.  This is so that every request passes through the request
> preprocessor first.
> So the flow is always request -> action -> page.
> Ideally the page doesn't know anything about any other pages, so I needed an
> action that could choose other actions to execute.  The actions that this
> workflow action use are configurable, and the choice is made based on
> information in the request.
> Besides choosing which actions to execute, the workflow action also forwards
> any output from one page, i.e. request parameters, to the next action in the
> workflow.
> To do this, I separately configure pages and actions.  Actions specify a
> logical name for a page (just like struts), but the logical page is defined
> separately from the action and it can have more than just a path attribute.
> In this case, a page definition includes the names of the request parameters
> that it produces.  From this attribute a workflow action can tell what
> request parameters from the current request should be forwarded to the
> WebPage (ActionForward).  The forwarded parameters are stored in a class
> called WebContext (though ActionContext would be a better name); the
> WebContext is added to the request with setAttribute; and I have static
> helper methods (soon to be custom tags) than can automatically add this
> context data to a hyperlink.
> (sorry for the long explanation)
> > There was a proposal to extend the recent ActionForward mapping
> > values (that let
> > action classes refer to pages by logical names) into a global
> > resource that can
> > be accessed from a custom tag.  Then, in your page, you could generate a
> > hyperlink or button (for example) based on the logical name of
> > the next action
> > in the view.  Does that sound like it would be useful in your scenario?
> >
> I'm kinda doing this now, but without exposing the logical page inside the
> page since I want the pages to only refer to actions.  If I could extend the
> attributes of a logical 'PageMapping' just like an ActionMapping, then I
> think this would be a great feature.
> David
> > >
> > > David
> >
> > Craig
> >
> >

View raw message