I found a couple of problems with getLastModified on JRun (2.3.1,
build 145). The headers were not being set as expected. Another problem
was the behavior from Netscape was different than for IE. It appears
that
Netscape has a non-conformant header for last modified -- the date is
different and they put the file size in the header after a semicolon.
Maybe I'm missing something obvious but I couldn't see what it was, and
my workaround does the job.

Here's what I ended up doing:

    private static final SimpleDateFormat lastModifiedFormat =
        new SimpleDateFormat("EEE, dd MMM yyyy hh:mm:ss zzz");

    private static final SimpleDateFormat netscapeLastModifiedFormat =
        new SimpleDateFormat("EEE, dd-MMM-yy hh:mm:ss zzz");

   /**
     * Calls doPost unless the file is a static file that has not
changed
     * since the browser last saw it.
     */
    protected void doGet(HttpServletRequest req, HttpServletResponse
resp)
        throws ServletException, IOException
    {
        if (!isModified(req, resp, DISPATCH_SERVLET_PATH)) {
            resp.setStatus(resp.SC_NOT_MODIFIED);
            return;
        }
        doPost(req, resp);
    }

    /**
     * Returns true if the requested file has not been modified since
the
     * last time the browser loaded it.
     */
    private boolean isModified(HttpServletRequest req,
                               HttpServletResponse resp)
    {
        String uri = req.getRequestURI();
        boolean isMod = true;

        // Substitute whatever code you need for calculating changes:
        long lastMod = getFileModifiedTime(req, resp, uri);

        if (lastMod != -1) {
            resp.setDateHeader("Last-Modified", lastMod);
            String sinceHdr = req.getHeader("IF_MODIFIED_SINCE");
            long since = -1;
            if (sinceHdr != null) {
                int semiIdx = sinceHdr.indexOf(";");
                if (semiIdx != -1) {
                    sinceHdr = sinceHdr.substring(0, semiIdx);
                }
                Date sinceDate = null;
                try {
                    sinceDate = lastModifiedFormat.parse(sinceHdr);
                } catch (ParseException exc) {
                    try {
                        sinceDate = netscapeLastModifiedFormat.parse(sinceHdr);
                    } catch (ParseException exc1) {
                    }
                }
                if (sinceDate != null) {
                    since = sinceDate.getTime();
                }
            }
            if (since > 0 && lastMod >= since) {
                isMod = false;
            }
        }
        return isMod;
    }

HTH,

Rod McChesney, Korobra


Suzanne Morine wrote:
>
> What are people doing to make the browsers use the cache copy
> unless the content is different than the last time? I am using
> getLastModified to return the new time and the browser/servlet-
> runner combination are not acting as expected. I could try all sorts
> of combinations of things, but I thought I would ask how people
> have done this sort of thing.
>
> I have a servlet that echos to the console every time
> getLastModified is called and every time doGet is called, so I know
> what is happening. My manager wants the visitor to not have to
> wait for a new download if it is right in cache and has not changed.
> My (Netscape) preferences are to compare dates of a cached
> document with those on the server with each new session,
> but this is what is happening:
>
> user action             OBSERVED RESULT
> ----------------------------------------------------------------
> reload                  USES AND IGNORES getLastModified: reloads
> shift-reload            does not use getLastModified: reloads
> later use URL:POST      USES AND IGNORES getLastModified: reloads
> later use URL:GET       USES AND IGNORES getLastModified: reloads
>
> I could not find a setting in Jrun that could be affecting this.
> What is very frustrating, is that using servletrunner in
> development did not produce these results. They still weren't
> as expected, but they were much better than this.
>
> Also, I looked in the list archives and found someone describing
> how to set the header in the doGet method and exit if there
> had been no change (and have no getLastModified method), but
> this gave me an empty document. If someone could shed some
> light on the way reload really works, preferably with an example that
> works, it would really help us.
>
> Suzanne Morine
> ARITEK Systems, Inc.
> [EMAIL PROTECTED]    <http://www.aritek.com>
> (303) 713-1401 ext. 311
>
> ___________________________________________________________________________
> 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

___________________________________________________________________________
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