How to handle caching of GWT theme CSS files

2019-04-07 10:08发布

I've got an app written with Struts/Tiles/JSP that I'm adding a GWT app to. The non-GWT portion of my app handles css caching by actually writing out the css file with a version number taken from my svn repository attached, like this "styles.css?svnbuild=12345". That way I can tell the browser to cache those css files forever and when I deploy a new version all my users download it immediately.

Now I'm moving on to the GWT app and I love how it uses "longmd5sum.cache.css" as the filename so I can still tell the browser to cache it forever. The problem is that the css files associated with my theme, like "gwt-standard.css", don't have a strong name and don't have my svnbuild parameter attached. Whenever I deploy a new version of my app, users are still seeing the old version of the css which makes it look wrong.

Has anyone figured out a best practice for handling caching of gwt theme css files? Is there a way I can append an svnbuild parameter or something similar when appending the css to the document?

2条回答
Luminary・发光体
2楼-- · 2019-04-07 10:45

Ok. So after I posted this I dug into the GWT source code and found some links about creating a GWT custom linker.

http://development.lombardi.com/?p=29

http://code.google.com/webtoolkit/doc/1.6/DevGuideOrganizingProjects.html

Here's how I solved it with my own linker. First I made a linker class that extends the standard IFrameLinker:

@LinkerOrder(LinkerOrder.Order.PRIMARY)
public class MyLinker extends IFrameLinker {
    protected String generateStylesheetInjector(String stylesheetUrl) {
        stylesheetUrl = stylesheetUrl + "?buildtime=" + System.currentTimeMillis();
        return super.generateStylesheetInjector(stylesheetUrl);
    }
}

After that it's just a matter of telling your module to use your custom linker. In your module.gwt.xml file:

<module>
    <define-linker name="mylinker" class="com.company.gwt.core.linker.MyLinker" />
    <add-linker name="mylinker" />
</module>

Just tried it out and now in my nocache.js file it outputs a new timestamp every time I compile. My users can cache the css file forever and they will download a new one automatically whenever I deploy a new version of the app.

查看更多
劫难
3楼-- · 2019-04-07 10:50

Seems like the preferred thing to do now is to use ClientBundles rather then separate CSS: Google Css Resource Cookbook . We recently made this transition quite painlessly with the following (with obviously some future intent to eliminate the @CssResource.NotStrict annotation):

public interface OurCssResources extends ClientBundle {

    @Source("ourCSS.css")
    @CssResource.NotStrict
    public CssResource getCss();
...

Then in the root of our application:

private void injectAllCss() {
        OurCssResources resources = GWT.create(OurCssResources.class);
        resources.getCss().ensureInjected();
...

This is kind of a heavy handed approach, but it solves the problem, and it puts you on the road to doing things the google intended way.

It looks like you can get even closer to their intended way fairly automatically (although I haven't tried these on 2.4, the stuff I mentioned above did work under 2.4 (I did have a problem with an external dependency (GXT); but since that won't change i just left it using the old fashioned method.

查看更多
登录 后发表回答