The answer to this question may already be online, but I cannot figure out how to ask it without getting irrelevant results. In a Java web project where I use servlets and have a web.xml
deployment descriptor, aside from servlets, is there a way to create custom mappings for any URL resource? For example, html files, Javascript files, images, style sheets, etc.?
The reason I ask has to do with browser caching. Between releases of a web project, if a resource gets cached, and then an update rolls out, the browser will typically try to load the cached version first. In places where DOM elements and Javascript functions have changed or been updated, this can lead to the updated page just breaking due to unsynchronized resources.
Now I have heard of a lot of solutions to this problem:
index.html
becomes index.html?v=1.2
in one release, and then index.html?v=1.3
in the release after, preventing cache overlap. My worry with this is that not all browsers implement a caching policy that respects this.
Issue: Where one browser may cache the file as index.html?v=1.3
, another browser may just cache index.html
and add the URL parameters to it after loading it from the cache, and another browser may just not cache files with URL parameters at all.touch
all files on the server between releases. This way, when the HTTP request for a resource is sent, and the response header shows that the retrieved file has a newer timestamp than that of the cache, it will reload. Issue: Again, I am not certain that all browsers implement any such caching policy.index.html
becomes index.1.2.html
. This would be the end-all be-all solution, since caching is done at the file name level, and when we move to release version 1.3, there is no possible way the browser already has index.1.3.html
cached already. Issue: Source control management on the development side becomes a nightmare......Unless, there was a way to map index.1.3.html
to a server-side resource simply named index.html
. This gets back to my original question, can this be done in a web project? Is this even recommended? I know in web.xml
, we can map URL patterns to servlets, but can we have URL patterns mapped to other resources? It seems it would be so easy to just maintain a single descriptor file between releases, so that on the client end, it appears that all files are new, so there will definitely be a loading hit the first time the new release is loaded, but caching out of sync resources would be eliminated this way.
A viably simple solution to this issue in a Java web application would actually not require mapping, nor would I have to alter the web.xml
deployment descriptor at all. Instead, the method of building the web project would simply have to change ~ which typically means altering the build script. A slightly different approach to merging the version with the file name would be to merge the version with the URL path. For example, index.html
would be accessed via HTTP here for release 1.2:
/doc-1.2/index.html
And then for release 1.3, it would be accessed here:
/doc-1.3/index.html
index.html
, as well as all other HTTP resources would remain untouched. This solves the source control issue.index.html
file, all web-application-specific resources would be required to be relative to the path of index.html
. This relieves the need for having an extra component, such as a servlet, embed the version number into each referenced resource when the file is loaded from the server./
(as in http://hostname.domain.com/AppName/
) would be a servlet that redirects to the actual entry point based on the current release. For example, in release 1.2, the entry point /
(or index.jsp
) would do a simple redirect to doc-1.2/index.html
, and then this would change to doc-1.3/index.html
in release 1.3.WebContent
directory to a destination point of doc-<release #>
in the build web application.Therefore, the only two things that would have to change between releases are the entry point redirection and the build script. As mentioned in the original question, when a new release is deployed, the entry point will now redirect the client web browser to doc-1.3/index.html
, and all resources will now be relative to the path doc-1.3
, and there is no possible way that the browser could already have anything cached with a prefix of doc-1.3
.
The one issue that this method does not address is what happens if a client bookmarks a version dependent resource in their browser, say http://hostname.domain.com/AppName/doc-1.2/index.html
, when the newest release version is 1.3. They would ultimately get a 404 because on the server, no such doc-1.2
directory exists (as a result of the build script only creating the directory necessary for the current release). The simplest solution around this problem that I can think of would be to make one additional servlet, and map all previous release versions to it. The servlet would always either redirect the user to the actual entry point, or redirect the user to the same resource but in the current release. So by the time the web application is to release 1.5, the "previous version redirect servlet" would be mapped to all of /doc-1.0/**
, /doc-1.1/**
, /doc-1.2/**
, /doc-1.3/**
, and /doc-1.4/**
(which includes all sub-paths of those directories). This solution would simply require that all previous versions be accounted for and maintained in this servlet mapping.