<img height="1" width="1" style="display:none;" alt="" src="https://px.ads.linkedin.com/collect/?pid=299788&amp;fmt=gif">

Angry Cache Busting in Spring MVC

Software Development, Spring, Software Solutions

By Joel Brinkman

I was tasked recently with helping find a way to guarantee the users of a web application could be forced to reload static JavaScript files deployed with the application. While there are many well-understood methods for dealing with this common problem, I decided I wanted to reinvent the wheel so I might have another topic for a blog post.

What I came up with is a simple filter that allows the browser to request any resource at its natural URL and a URL that includes some arbitrary text contained in the path. For example, the following might be a valid URL: http://somehost.com/myapp/js/foo.js for some awesome JavaScript contained in foo.js. Once our filter is configured, the same resource is available at: http://somehost.com/myapp/buster/somestuff/js/foo.js. This becomes more interesting when we consider a more realistic example URL: http://somehost.com/myapp/buster/1.1/js/foo.js where 1.1 in my example is the release number for our application.
Instead of changing the names of static resources and the URLs that reference them, with our filter we simply add some arbitrary text (or an application version number) to the URLs when we render them. How might such an amazing servlet filter be constructed? As you have probably guessed, it's pretty easy.

public class BusterFilter extends GenericFilterBean {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
String url = ((HttpServletRequest) request).getRequestURL().toString();
url = StringUtils.substringAfter(url, "buster/");
url = StringUtils.substringAfter(url, "/");
url = "/" + url;
getServletContext().getRequestDispatcher(url).forward(request, response);

As you can see, this filter simply fixes applicable URLs and forwards the request. How do we handle this in the view? It's equally simple. If, for example, we want to force the browser to reload each resource once for each session, in our JSP we might assign a variable that contains the session ID and then use this to render URLs.

<c:set var="busterBase" value="${base}/buster/${pageContext.session.id}" scope="request" />

And then when loading a resource:
<link href="${busterBase}/styles/reset.css" type="text/css" rel="stylesheet"/>
BAM!!! Everything gets loaded fresh and easy!

TAGS: Software Development, Spring, Software Solutions

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Subscribe to Our Newsletter

Recent Blog Posts