This week's book giveaway is in the OCAJP 8 forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line! See this thread for details.
Something I never quite understood is how JSPs control client caching.
The content returned by a servlet/JSP is dynamic in nature: tags, scriptlets and espressions are evaluated to generate the content sent to the client. Therefore, every call to a URL needs to "run" the JSP to have a fresh copy of the page content generated. On the other hand, I've seen the opposite -- for example, when coding data feeds I've needed to add some kind of bogus "nocache" query parameter to the client URL to ensure the browser doesn't use its cached copy.
So.. What's going on such that JSPs seem to get evaluated each time without my intervention, yet some times I need to do something, like a "nocache" query parameter, to force a new copy?
I just tried a test. My JSP simply returns the current time. The response headers (provided by Tomcat) are:
Date:Fri, 12 Aug 2011 15:09:48 GMT
Nothing about the cache, as discussed in the article, yet the client *is* re-running the JSP every time I refresh the page. So why *isn't* it caching?
That is a result of a bunch of factors that might be impossible to control. The browser may decide to not cache a response over any number of factors that aren't guaranteed to be consistent across all browsers. It'd be highly unusual to want a dynamic resource to be cached -- what are you actually hoping to accomplish?
Joined: Nov 06, 2000
Let's start over...
Here's my original question: "The content returned by a servlet/JSP is dynamic in nature: tags, scriptlets and espressions are evaluated to generate the content sent to the client. Therefore, every call to a URL needs to "run" the JSP to have a fresh copy of the page content generated. On the other hand, I've seen the opposite -- for example, when coding data feeds I've needed to add some kind of bogus "nocache" query parameter to the client URL to ensure the browser doesn't use its cached copy."
I want it to call my page each time. And it does. But I don't know why. In my simple example, which is a JSP that contains
every time I refresh I see the new time. This is "normal" and not surprising -- we all take it for granted. But when I look in the response header I see nothing about preventing caching. So I'm asking how the client knows *not* to cache a typical JSP page like this.
I already answered. The browser is deciding not to cache the page. You seem to want to know exactly why. It may do so for any number of reasons and we have no idea what those reasons might be, or if another browser will act the same way. The safest thing to do is to add the appropriate headers to make sure that response will not be cached. Relying upon the implicit behavior may bite you down the road.
If you want more explicit answers, you'll need to start looking at browser source code.
First of all I commented out the code which sends all those "Don't Cache" headers. Then I ran my application in Firefox with HttpFox turned on to monitor the requests and responses. And what I found was this:
For requests for things like CSS and GIF files, the browser would send an If-Modified-Since header and get a 304 (Not Modified) response. So, normal caching behaviour going on there.
But for requests to servlets (no file extension on the URL) the browser didn't send any If-Modified-Since header and always got a 200 (OK) response. In other words, the servlet was always executed.
I don't have any URLs which request JSPs directly (they are all fronted by servlets) so I couldn't test what happens with JSPs. Also note that I only tested with Firefox and not with other browsers, so you may want to do your own experiments.
(Edit: My guess is that for a URL ending in ".jsp" the browser will send an If-Modified-Since header, but the server will ignore that since by design a JSP is supposed to be dynamic. That's just a guess, though, which could be tested by an experiment.)
Edit: URLs with parameters also got the If-Modified-Since header.
Joined: Nov 06, 2000
Oh. The answer is "I don't know." That would have saved some time in this discussion...
As far as the idea that differing browsers may have other behavior, I doubt it. I've never seen differences in browsers in the "normal" case illustrated by my example -- all browsers consistently re-fetch the result every time the page is visited. Again -- this is the behavior we want, and I see no inconsistencies across browsers.
As far as why I want to know... It seems natural to want to understand what's going on in a technology... I just realized I couldn't differentiate the circumstances when manual intervention is needed, and when it isn't -- I tend to simply discover that a page is cached during testing, and add code to address it. 90% of the time it doesn't cache, which is good -- I just don't know the exact circumstances when the client chooses to do so, or not to do so. In other words, I know how to force no caching, as explained in the article you linked, but I don't know how to predict when that will be necessary. And I'm uncomfortable with that lack of understanding.
I thought someone might know here.. As you suggest, I'll keep digging elsewhere. I'm sorry I brought up what turned into an conversation wrought with mis-communication and misunderstanding.
[I wrote this before Paul's response. Thanks for trying that out. It's interesting. I'll get a sniffer and do some more digging. To answer the earlier question of why I'm going down this path: I'm playing with the unrelated topic of HTML5 application caching, and the cache manifest. In my design, it may be convenient to flag or "tough" the manifest programmatically, in order to force the browser to re-read the manifest. But before going down that path, I wanted to understand how it all works...]
Max Rahder wrote:Oh. The answer is "I don't know."
No, the answer is "we (as in the user of browsers) don't know". One thing we must get used to as web developers is that the browsers don't always exhibit deterministic behavior, and differences across the browsers with regards to how they behave is rote.
As far as the idea that differing browsers may have other behavior, I doubt it.
It exists. I have the scars and war stories to tell my grandchildren.
In certain cases they may all behave the same way. But make s subtle change, and suddenly IE (or some other browser) may start acting differently.
As far as why I want to know... It seems natural to want to understand what's going on in a technology
Sure it is. WHo has said anything otherwise. What I'm trying to get across, is that sometimes the answer is not explicitly known.
I'm sorry I brought up what turned into an conversation wrought with mis-communication and misunderstanding.
But what I'm really trying to get across -- and I'm not saying you are doing this -- is that relying upon the implicit caching behavior can be dangerous. So saying "Well, the browsers all seem to not cache JSP page automatically, so I don't need to set any caching headers" is not a good idea.
Subtle changes, to the code, or mere updates to the browser, might change the implicit behavior. So it's far safer to be sure and set the caching headers explicitly.
One of those war stories involves the AOL server (thankfully an artifact of the past) deciding to start caching JSP pages out of the blue. Customers are so over-joyed when they start seeing data from other peoples' account! Not!
While actual employment of client-side caching is strictly at the whim of the client and its cache settings, the server can have an effect as well.
For security reasons, the Tomcat webapp server overrides caching when sending secured content. This can have a MAJOR impact on clients who would otherwise cache when your app pulls a couple of hundred KB of AJAX support library and/or large page background images.
I had a lot of fun last year convincing Tomcat that it was OK to allow those items to be cached.
An IDE is no substitute for an Intelligent Developer.