【问题标题】:Cache static files by content type in Spring Boot在 Spring Boot 中按内容类型缓存静态文件
【发布时间】:2020-05-29 18:35:30
【问题描述】:

我正在尝试在 Spring Boot 中为特定静态文件类型设置缓存标头。 在目录 src/main/resources/static 中有几个不同文件类型的子目录:

src/main/resources/static/font   --> *.otf
src/main/resources/static/lib    --> *.js
src/main/resources/static/images --> *.png, *.jpg

有没有办法在 Spring 配置中按文件类型放置缓存头?

*.otf 365 days
*.png 30 days
*.jpg 7 days

Spring 版本是 5.2.3 和 Spring Boot 2.2.4 - Spring Boot 是否有可能处理它并使其不起作用?

试过

@Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
    final CacheControl oneYearPublic = CacheControl.maxAge(365, TimeUnit.DAYS).cachePublic();
    // it does not "work" with "/static/fonts/"
    registry.addResourceHandler("/fonts/{filename:\\w+\\.otf}").setCacheControl(oneYearPublic);
}

但我得到了奇怪的结果。当检查 DevTools 的 Network 选项卡时,我得到了这些标题:

    Cache-Control: no-cache, no-store, max-age=0, must-revalidate
    Pragma: no-cache
    Expires: 0

但是当我直接访问 URL 时,我得到 404

http://localhost/fonts/1952RHEINMETALL.otf

如果没有任何配置,我会得到“no-store”Cache-Control 标头。

【问题讨论】:

    标签: spring spring-boot caching http-headers content-type


    【解决方案1】:

    我已经设法为这个问题找到了一个可行的解决方案。检查 GitHub 存储库https://github.com/alexsomai/cache-static-assets。

    这是一个应该可以工作的配置示例:

    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            Objects.requireNonNull(registry);
    
            // could use either '/**/images/{filename:\w+\.png}' or '/**/images/*.png'
            registry.addResourceHandler("/**/images/{filename:\\w+\\.png}")
                    .addResourceLocations("classpath:/static/")
                    .setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS));
    
            registry.addResourceHandler("/**/images/*.jpg")
                    .addResourceLocations("classpath:/static/")
                    .setCacheControl(CacheControl.maxAge(2, TimeUnit.DAYS));
    
            registry.addResourceHandler("/**/lib/*.js")
                    .addResourceLocations("classpath:/static/")
                    .setCacheControl(CacheControl.maxAge(3, TimeUnit.DAYS));
        }
    }
    

    您可以根据文件类型和缓存持续时间轻松调整它以满足您的需要。

    作为关键要点,请确保添加 addResourceLocations 函数(没有这个函数,您会得到 404)。另外,如果您使用的是 Spring Boot,则不需要@EnableWebMvc,因为它最初是在此示例中发布的https://stackoverflow.com/a/33216168/6908551。

    【讨论】:

    • 之前尝试使用资源处理程序,但结果很奇怪。现在我更新了原始问题,让您看到这些结果。知道发生了什么吗?
    • 404 告诉我您在访问/fonts/1952RHEINMETALL.otf 时遇到了不同类型的问题。如果您尝试访问/static/font/1952RHEINMETALL.otf 或/font/1952RHEINMETALL.otf(不带s)怎么办?您确定将 URL 正确映射到静态资源吗?
    • 我已经设法为这个用例创建了一个可行的解决方案 :) 检查 GitHub repo github.com/alexsomai/cache-static-assets(我也会用正确的版本更新我的答案)。最初的示例中似乎缺少addResourceLocations。
    • 现在我可以确认当 /**/ 作为前缀添加到 addResourceHandler() 参数时它可以工作。谢谢!
    • 仅供所有将来阅读此内容的人记录 - 请注意您自己处理 URL 映射的黑客行为:我希望将 favicon 映射到我的项目的根目录,但要在其中包含文件资源目录;要拥有它,我必须创建 SimpleUrlMapping bean 和 ResourceHttpRequestHandler。标头应在 ResourceHttpRequestHandler 内另外处理。
    猜你喜欢
    • 2018-02-10
    • 2016-11-07
    • 1970-01-01
    • 2017-03-25
    • 2011-08-19
    • 1970-01-01
    • 2018-06-26
    • 1970-01-01
    • 2017-07-19
    相关资源
    最近更新 更多