Spring Bootで静的コンテンツにフィンガープリントをつける

2015/04/14
2021/02/25

Spring BootではRuby on Railsのアセットパイプラインのようなものをどうやって実現するのか?というのを調べていた。
Sprinb Bootのバージョンは1.2.3-RELEASE。

以下のSpringのブログによれば、静的コンテンツのハンドリングはSpring Framework 4.1で改善されたらしい。
Spring Framework 4.1 - handling static web resources

JavaScriptの開発については、grunt、gulp、Dart、TypeScriptなどネイティブのものを使ってくれ、とある。
確かに、こちらの進化の速度は速いので直接こういったツール等を使う方がいい。結合・圧縮はこちらでできる。

あとは、リソースにフィンガープリントをつける(app-ハッシュ値.cssなど)方法だが、これは"Resource versioning"と呼んでいる。
(知らなかったが、こういうのを"Cache busting"というらしい。)

Showcase applicationがあるよ、と紹介されており、こちらを動かしてみれば期待しているものかわかりだったが、上手く動かず・・・。
見よう見まねで、作成中のサンプルアプリに組み込んでみた。

結論から言うと、以下のようなクラスを追加するだけだった。簡単。

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
    @Bean
    public ResourceUrlEncodingFilter resourceUrlEncodingFilter() {
        return new ResourceUrlEncodingFilter();
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        VersionResourceResolver versionResolver = new VersionResourceResolver()
                .addContentVersionStrategy("/css/**", "/js/**");
        registry.addResourceHandler("/**")
                .addResourceLocations("classpath:static/")
                .setCachePeriod(null)
                .resourceChain(true)
                .addResolver(versionResolver);
    }
}

addContentVersionStrategy()で指定しているのが、バージョニングする対象のリソース。
/css/**/js/**は、今回はここにリソースを配置していたというだけなので、適宜読み替えが必要。
また、上記では使っていなかったがライブラリのJavaScriptなどにバージョンをつける場合はaddFixedVersionStrategy()を使えば、固定のバージョンをつけられるらしい。
上記Showcaseアプリではapplication.ymlに定義した値を読み込ませていた。
これはこれでいいが、バージョンの更新を忘れそう。
Gitのコミットハッシュ値を自動的につけられるなら利用したいが…これはまた別の機会に考えてみる。
(2016/03追記: ライブラリのバージョニングについてはこちら → Spring BootでJavaScript/CSSライブラリにフィンガープリントをつける)

addResourceLocations()がバージョニングしたファイルを配置する場所を指定する(と思われる)。
上記はバージョニングができることを確認したいだけだったのでごく簡潔な内容にとどめたが、実際にはアプリケーションのProfileによってキャッシュの設定を切り替えるのが良いようだ。
(Showcaseアプリを見るとわかる)

resourceUrlEncodingFilter()については、ただnewしているだけだが、これがないとバージョニングが適用されなかった。

HTML側で、CSSやJSの指定の仕方が変わるかというと、そのままだった。
ShowcaseアプリはGroovyのテンプレートを使っておりThymeleafだとどう書くのだろうと考えてしまったが、通常通りth:href="@{/css/main.css}"などと書けば自動的に変換される。

© 2010 ksoichiro