Drew Cox wrote:
[snip background info description]

> So, on to the question (I think I will have to keep a copy of that for all
> my further queries...:-)
>
> The action class perform( ) method actually needs access to additional
> resources beyond the HttpServletRequest and HttpServletResponse shown in the
> simplified example above.  In our case most need acces to the custom
> application logging service, security manager and database connection pool,
> all of which are stored in the application scope.  This sort of requirement
> must be common for others out there implementing this model?
>

I use a very similar model to the one you are describing, and have encountered the
same sorts of benefits.  I deal with the issue you raise here in the way my
perform() method is defined:

    public interface WebAction {

        public void perform(HttpServlet servlet,
          HttpServletRequest req, HttpServletResponse res)
          throws ServletException, IOException

    }

As you can see, I'm passing a reference to the calling servlet (passed as "this"),
along with the specific request and response I am dealing with.  (Alternatively, I
suppose you could make the servlet a JavaBeans property of the action class, and
have the controller servlet set it the first time that the action instance is
loaded).

Passing the servlet reference lets me access any resources that the underlying
servlet can get.  For example, to grab a connection pool out of the servlet
context attributes, I do something this inside a perform() method:

    ConnectionPool pool = (ConnectionPool)
      servlet.getServletContext().getAttribute("pool");

and I can log things to the servlet log by saying:

    servlet.log("This is a message");

If the controller servlet itself had methods you wanted to treat as shared
functionality for your action procedures, you could pass a reference to your
servlet class instead of HttpServlet if you wanted.  I've got a generic controller
servlet that does all the common stuff (request parsing, loading and caching the
action class instances, calling the correct one), which I can subclass to provide
additional shared functionality that is unique to a particular web application.

>
> Currently I am just having the controlling servlet extract references to
> these beans from the application scope and passing them as parameters to the
> action class perform( ) method.
>

Doesn't that mean that the method signature for perform() changes for each
action?  That would seem to require changes to the controlling servlet as you add
new actions that require different signatures.  In my model, the call to perform()
is the same for all actions.

>
> However, in the Sep 99 JavaWorld acticle on the above model, they
> recommended bundling these sorts of additional parameters into a "services"
> array of Objects, to pass them as a single parameter to the perform( )
> method.  I can see some benefits to this, for example, you can readily add
> new services to this array without changing the WebAction interface and
> breaking all your existing implementing classes.  However, I don't like the
> idea of hiding the identity of these service classes as positions in an
> array of Objects, then getting run-time ClassCastExceptions when I (or more
> likely one of the other developers ;-) get the positions wrong.
>

I would certainly not access things positionally (such as with an array subscript)
if I used this approach.  It would make more sense to send a Hashtable type
collection that you can access resources by name.  But even this would seem to
involve the control servlet in request-specific work (deciding which resources a
particular action method cares about).  There is also a non-zero amount of work
allocating a new Java object for the collection, and then filling it in -- and you
are paying this cost on every single request.

>From a design viewpoint, there's an additional question.  Let's say you've built a
particular web action, and you want to enhance it.  But now, it needs an
additional resource out of the servlet context attributes that was not required
before.  Do you need to go back to your controller servlet and add an additional
services object to the collection?

>
> I have also seen a slight derivation where the services are bundled into a
> Hashtable and passed to the perform( ) method.  As I see it, you might as
> well just pass a reference to the ServletContext and let the action class
> extract the services themselves.
>

See above for a note on the performance issue related to this.

>
> So, if your still following (and awake), how do people handle this
> requirement.  Should I just "keep it simple stupid" and stop thinking about
> it too much?
>

These are important issues to think about now.  As your application grows, it
becomes progressively harder to change these types of fundamentals, because you've
got so many classes relying on the way it currently operates.

>
> Much appreciated,
>
> Drew Cox
> Barrack Consulting
>

Craig McClanahan

===========================================================================
To unsubscribe: mailto [EMAIL PROTECTED] with body: "signoff JSP-INTEREST".
FAQs on JSP can be found at:
 http://java.sun.com/products/jsp/faq.html
 http://www.esperanto.org.nz/jsp/jspfaq.html

Reply via email to