On Wed, 10 Apr 2002, Steven D. Monday wrote:
> Date: Wed, 10 Apr 2002 08:30:33 -0500
> From: Steven D. Monday <[EMAIL PROTECTED]>
> Reply-To: Struts Developers List <[EMAIL PROTECTED]>
> To: Struts Developers List <[EMAIL PROTECTED]>
> Subject: Re: Servlet 2.3 filter
>
>
> "Craig R.
> McClanahan"
> <craigmcc@apa
> che.org>
>
> 04/09/2002 To: Struts Developers List
><[EMAIL PROTECTED]>
> 10:27 AM cc:
> Please
> respond to
> "Struts
> Developers Subject: Re: Servlet 2.3 filter
> List"
>
>
>
>
>
>
>
>
>
> Caterpillar: Confidential Green Retain Until: 05/09/2002
> Retention Category: G90 -
> Information and Reports
>
>
>
> I do appreciate your response and have a couple follow up questions.
>
> > How do you set up the data the *first* time you want to
> > access a particular page (the way you'd use a setup action
> > in a Struts based app)?
>
> Not sure I can comment on this issue since we're very new to the Struts
> world but I would like to hear a scenario in which "setup actions" would be
> applied.
>
Using a filter for the controller would not change the basic application
paradigm for Struts-based apps - you would still use a setup action first.
The canonical example for this is you want to do a typical "master file
maintenance" type application in a webapp (for example, to maintain
customer records). The form for a new customer and an old customer are
very similar, so you'd like to use the same page for both transactions.
A typical way to set this up in Struts:
* To set up a new customer, call the action
"/setupCustomer.do?action=create"
* To set up an old customer, call the action
"/setupCustomer.do?action=Edit&customer_id=123456"
* In SetupCustomerAction, you set up a new CustomerForm
bean. Then, if the "action" parameter is "create" you
configure it with all the default values for a new
customer. If the "action" parameter is "edit" you go
grab the data out of the database, and prepopulate the
form. I usually add the "action" parameter as a property
of my form bean (and use a hidden field on the form) so
that the save action called later knows what kind it was.
Finally, SetupCustomerAction forwards to the appropriate
"edit customer" page via an ActionForward.
* In the edit customer page, the customer form bean will
already exist, and you just display the entry form. If
you are editing, the previous values will be there automatically.
You can make decisions to display things differently (for example,
you might let a new customer set their own id but disable the
ability to change it on an existing customer) with <logic:present>
and <logic:equals> type tags.
* The edit customer page includes the "action" property as a hidden
field, and submits to a "/saveCustomer.do" action which ultimately
calls SaveCustomerAction.
* When the form submit happens, the validate() method of the customer
form bean is called in the usual way, so the user might be returned
to the input form again.
* If the input data is ok, SaveCustomerAction must perform the database
updates needed to reflect the required changes. If you are talking
to the database directly from an Action, you would construct an
appropriate INSERT or UPDATE statement, depending on what the "action"
property was. Alternatively, you can just package up the required
data in a value object and send it off to the appropriate EJB or
whatever, calling a "create" or "update" method depending on the
"action" property.
The /struts-example webapp included with Struts illustrates this design
pattern on a very small scale. For a larger scale example, we're building
an administrative webapp for Tomcat 4 based on Struts (1.0.2 at the
moment) that follows this pattern all over the place. To take a look,
grab a recent nightly build of Tomcat 4 from
<http://jakarta.apache.org/builds/jakarta-tomcat-4.0/nightly>
(source code drops are in the "src" subdirectory underneath. An
interesting aspect of this app is that the "database" is really a set of
JMX MBeans that correspond to the internal components of Tomcat 4.
> > What happens when a particular form submit should be handled
> > differently (and trigger different output) depending on the
> > contents of the included fields?
>
> I believe that filters can exercise the option to handle the
> request/response themselves or to forward the request/response to the next
> filter in the chain. I would think that should it be the case that if a
> filter chose to evaluate request parameters and handle the response in a
> different fashion (e.g. dispatch to a different jsp) dependent upon
> parameter values it would have that perogative.
This scenario can be handled just like it is today -- the action to which
the form is submitted is perfectly free to send the request wherever it
needs to, based on the received input fields.
>
> > What happens when you successfully complete a transaction and
> > want to go on to the next one (you can't just forward to the
> > "new" page because filters won't get invoked again)?
>
> Could you give me some further insight into this comment, particularly with
> regard to the phrase "complete a transaction"? I'm no doubt looking at
> this filter concept from too simplistic a perspective. Could you describe
> a transaction scenario? I suppose I was looking at a filter chain that
> might include a security filter, followed by a business logic filter,
> followed finally by a view dispatching filter. In other words a
> "transaction" would include authentication/authorization, action and
> response generation. I don't think in this simple example I would
> want/need filters to be invoked again before the jsp is dispatched to. I
> suppose if I did I would include filters in the above mentioned chain that
> would to additional view related manipulation of my business logic filter's
> output before the jsp filter.
>
For "complete a transaction", look at what SaveCustomerAction does in my
example scenario above.
However, the point being made in this sentence is an important one -- in
Servlet 2.3, filters are only invoked on the *initial* request, not on the
results of doing a RequestDispatcher.forward() call (which is what Struts
does to forward to an appropriate response page). That actually makes it
easier to write a controller as a filter, but harder to use filters for
some of the ways you might want to (like doing an XSLT transformation on
the generated output, depending on what user-agent submitted this
request).
The processing of the controller itself can be decomposed into separate
filters -- but I think the above comment was referring to application
level transactions, not internal controller processing.
> Thanks
>
Craig
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>