Geoff Soutter wrote:

> Nic Ferrier wrote:
> >But I am happy to applaud if Geoff or anyone else can give a reason
> >why getLM is derelicting it's duty.
>
> Nic, as I said before, you've only addressed one of the points I raised in
> my original message. Here they are again, perhaps you'd like to comment on
> the other two?
>
> 1) it doesn't allow you to easily share state with doGet(), which you almost
> always want to do

Geoff, there was another message thread a couple days ago (dealing with why
frame reloading worked differently when a servlet created the frameset versus a
static HTML page), in which I offered a design pattern that dealt with this
issue.  In case you didn't see it, the idea was this:

* Don't implement getLastModified() explicitly

* At the beginning of your doGet() method, define
  the logic needed to determine whether the page
  that this user has already cached is stale or not.

* If it is not stale, do the following:
        response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
        return;
  which is essentially what the HttpServlet.service() method
  does for you if you do implement getLM.

* If it is stale, or if the client does not have a current
  copy of the page (i.e. no "If-Modified-Since" header),
  go ahead and generate the page in the usual way.

Now, since you're doing everything in one doGet() method in the context of a
single thread, there shouldn't be any state matchup or code duplication issues,
right?  Of course, you still have to deal with state issues that cross multiple
requests, but that's a consequence of using a stateless underlying protocol
like HTTP.  I deal with that by keeping the state in user sessions, where it is
equally accessible to both getLM and doGet.

NOTE:  Even if this approach deals with your concern, that doesn't seem to be
enough justification to deprecate a call that is being used by other people,
and disrupting their lives unnecessarily.  :-)

>
> 2) there's no easy way co-ordinate error handling between getLM() and
> doGet() (you can't even throw a ServletException from getLM()).

Not being able to throw ServletException hasn't ever bothered me.  If my
servlet throws any exception from anywhere, then I consider my servlet to be
broken and in need of fixing -- whether caching works or not becomes
irrelevant.  Your next point covers other aspects of error handling.

>
> 3) getLM() will set LastModified even if doGet() fails and throws an
> exception. This means that the client will try and cache your "error" page
> (unless you do a sendError() or somesuch).

I think there's at least a few different issues here:

* If you do use getLM and it returns a time before
  the if-modified-since header in the request, your
  doGet() method will never get called, so it won't have
  any opportunity to throw an exception or display an
  error page.  See above for my beliefs about servlets
  that throw exceptions, but error pages are a legitimate
  concern.

* If your app sends back an error page of some sort,
  (say, input fields failed a validation test), then it's your
  responsibility to remember that on the subsequent
  request, so that you send back an appropriate
  last-modified time that forces a reload of the "real"
  page.  This is true if you are using getLM or if you are
  embedding your caching logic directly into doGet.

* If it's more convenient to combine the cache decision
  logic in your doGet(), you're welcome to do so.  But
  getLM works for other cases -- and disrupting
  existing running programs by removing functionality
  doesn't count in my book as "improving" the API,
  unless you offer a replacement that is demonstrably
  better.

There's been some discussion on supporting caching in the API among the servlet
experts group that reviews new API specs before they go public (I am a
member).  The challenge with caching is that it's very difficult to define, in
a standardized way, the rules to decide whether the cached version of a
response is stale or not.  HTTP proxies have the same kind of issues for
caching static pages, and it's taken a *long* time for the rules refined in
HTTP/1.1.

For any given app, this staleness decision might be based on combining any or
all of the following factors:  logged-in user, request URI, query parameters,
cookies, HTTP headers, browser making the request (in case you keep different
versions for different browsers), time of day (you might be producing updates
on some sort of regular schedule that invalidates the cached copy) and so on.
Proposed solutions to this, IMHO, suffer from a level of complexity far higher
than any other concept in the servlet API, and don't belong there.  Whether to
cache, and how to cache, seem to me to be application-level decisions, not
generic API level mandates.

At any rate, recommendations to deprecate something like getLM are not likely
to be persuasive, simply on the grounds that it works now, and is being used in
existing programs.  There's no overriding security issues like there were with
getServlet() and HttpSessionContext, so it doesn't even matter if something
else might really be a little better -- and there are apps for which getLM as
currently specified works just fine, and "better" simply means "leave it the
heck alone."


>
>
> Geoff
>
>

Craig McClanahan

___________________________________________________________________________
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff SERVLET-INTEREST".

Archives: http://archives.java.sun.com/archives/servlet-interest.html
Resources: http://java.sun.com/products/servlet/external-resources.html
LISTSERV Help: http://www.lsoft.com/manuals/user/user.html

Reply via email to