ClientBundle
introduced in GWT 2.0 allows you to bundle images and other resources in one file, this file is cached forever resulting in fewer server request.
That being said, GWT introduces a concept they call perfect caching. It works by splitting your application in several files named something like .cache.html and the md5 part always change when your application code or resources change. Then there's the bootstrap script, which contains the logic to look for the correct <md5>.cache.html
file and load it. The bootstrap should never be cached.
In your app server, you need to configure it something like this (Apache in this case)
<Files *.nocache.*>
ExpiresDefault "access"
</Files>
<Files *.cache.*>
ExpiresDefault "now plus 1 year"
</Files>
In this case it's set to cache for one year. As far as I know there's no setting to cache forever, that only means a very high expiration time.
Tomcat caching
In the case of Tomcat, as far as I know there's no cache control so it has to be done manually by setting the proper HTTP headers. This can be automated by the use of filters.
/*Please don't use this in production!*/
public class CacheFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
//cache everything for one year
response.addHeader("Cache-Control", "max-age=31556926");
chain.doFilter(request, response);
}
public void init(FilterConfig filterConfig) {
this.fc = filterConfig;
}
public void destroy() {
this.fc = null;
}
}
Then map the filter in tomcat or derivatives (such as glassfish), in web.xml:
<filter>
<filter-name>cachingFilter</filter-name>
<filter-class>CacheFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>cachingFilter</filter-name>
<url-pattern>*.cache.*</url-pattern>
</filter-mapping>