In a note to the jsp-feedback alias before the final spec was released, I
made an argument for including a caching facility in JSP-1.0. That
functionality didn't make it into the spec; and though of course I can see
how a JSP-1.1 taglib will likely fill in most of this gap, I still feel
that it was a mistake to leave such a standard need out of the spec. So,
I've written a simple caching implementation to demonstrate how I think
JSP caching might work, and it is available for any JSP author to use
under LGPL (use it for free, but only redistribute it under certain
conditions). I'm offering it to any fully-compliant JSP-1.0 or later
implementation for distribution under that implementation's own license. I
would still like to see something like what I've done make it into
JSP-1.1.
I work on a high-traffic commerce site that is currently run using GSP
<http://www.bitmechanic.com/projects/gsp/>. GSP has worked great for us,
but we haven't successfully separated presentation from logic, and it
isn't the best thing to be tied to one implementation. So, we'd love to
transition to JSP syntax, even if we keep using the GSP implementation
(which I believe is moving in the direction of JSP-1.0 compliance). The
one piece of functionality GSP has that I can't see how we would get from
a JSP implementation is caching.
On a store like ours, where inventory is limited and restocks can take an
indeterminate amount of time (not like Amazon, which can just go to the
distributor quickly, but more like eToys, where toy shipments are harder
to predict), pages must be updated and the customer must be made aware
when product runs out of stock. JSP, through the useBean tag, gives us
three possible tools with which we can periodically check inventory: (1)
scope = page or request; (2) scope = session; or (3) scope = application.
In case (1), checking inventory on every request is far too often -- the
database call is time-consuming, and most inventory does not change status
_that_ often. In case (2), once a session may be sufficient, but sessions
vary widely in length, and a long session could easily cause an inventory
problem. In case (3), the bean is left to its own devices to handle
inventory checks, and with a lot of beans making database calls, those
devices could vary or conflict -- or, if the bean is third-party, the JSP
author could simply be out of luck.
This seems to me to be a common problem. JSP pages are going to make
database calls _all_ the time -- I would go so far as to say I would
expect database integration to be the number one JSP application. The
scopes provided by useBean are not sufficient for this application, and so
many JSP authors will wind up pummeling databases and then complaining
about how slow java is all over again. Any dynamic page system must
consider and address how to avoid recalculating values and how to provide
service to the user as quickly as possible.
I suspect this functionality was deliberately left to bean authors in
order to make JSP-1.0 adoption an easier goal. My concern is that lack of
standardizatrion of this feature will reduce the portability of JSP pages.
I believe every implementation will need caching, and every
implementation, left to its own devices, will probably come up with
something different. Looking over our GSP pages, caching is used all over
them, to the extent that I couldn't even figure out how to port to JSP
without caching as a standard tool. Bean authors should not need to embed
caching in every bean -- that is a sure way to introduce subtle bugs all
over JSP, since caching done wrong can cause inscrutable problems.
My implementation is intended to be designed reasonably well but it has
been implemented quickly -- I make no pretenses that the code is what it
should be, just that the design is better than what is in JSP-1.0. The
package is called BeanCache, and the cache is implemented as a bean for
use on JSP pages. An alpha-0.2 release, which has not been extensively
tested at all, is available from <http://www.precipice.org/java/cache/>.
Here is sample JSP usage:
<jsp:useBean id="cache" class="org.precipice.util.BeanCache"
scope="application">
<jsp:setProperty id="cache" property="defaultTTL" value="30m"/>
</jsp:useBean>
<jsp:useBean id="foo" class="FooBean"/>
<% cache.put(foo); %>
fooString = <%= cache.getProperty(foo, "fooString"); %>
<% cache.setProperty(foo, "fooName", "foo is my name"); %>
<% cache.flush(foo); %>
If a taglib were available, or if this functionality were standard, you
could imagine the following usage:
<cache:put id="foo"/>
fooString = <cache:getProperty id="foo" property="fooString"/>
<cache:setProperty id="foo" property="fooName" value="foo is my name"/>
<cache:flush id="foo">
The basic idea is to provide a transparent cache for beans, so that any
bean you would use in a JSP page could get put into the cache, and the
cache could act as a proxy for accessor (get/set) methods. A bean
property accessed through getProperty() would be retrieved from the bean,
and then subsequent calls to getProperty() would return the cached value
until the value expired. After expiration, the next getProperty() call
will cause the cache to get a new copy of the value from the bean
directly. In this way the JSP author doesn't need to know if the value is
coming from the cache or the bean, but can instead make one method call
and get the needed value. Cache values can be keyed to certain
properties. There is also an interface included, called CacheControl,
that allows bean authors to regulate how their bean's properties are
cached, if at all.
BeanCache is feature-compatible with GSP caching, except it only works on
beans (not scriptlets, etc.). I would much prefer JSP be
feature-compatible with GSP caching.
I am putting this out in the hope it will be immediately useful to JSP
page authors; but also in the hope that JSP implementors will consider
using a standard design of the form I suggest, or even that Sun will
consider standardizing this functionality. I'd appreciate any comments or
code patches/suggestions anyone might have, including successful test
reports under different JSP implementations.
Marc Hedlund <[EMAIL PROTECTED]>
===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JSP-INTEREST". For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".