Spring MVC和Thymeleaf资源版本控制

Anı*_*ici 5 javascript java caching spring-mvc thymeleaf

资源层次结构我的项目

我正在尝试使用Spring Mvc 4进行资源版本控制.我使用百万美元模板引擎.但是不能使用以下代码.当加载页面时,我无法看到新版本的Url,当我查看页面源.那么我的代码中出现了什么问题?我想念的是什么?

@Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/static/theme*//**").addResourceLocations("/resources/static/theme/")
            .setCacheControl(CacheControl.maxAge(365, TimeUnit.DAYS))
            .resourceChain(false)
            .addResolver(new VersionResourceResolver().addContentVersionStrategy("/**"))
            .addTransformer(new CssLinkResourceTransformer());
    registry.addResourceHandler("/static*//**").addResourceLocations("/resources/static/")
            .setCacheControl(CacheControl.maxAge(365, TimeUnit.DAYS))
            .resourceChain(false)
            .addResolver(new VersionResourceResolver().addContentVersionStrategy("/**"))
            .addTransformer(new CssLinkResourceTransformer());
    registry.addResourceHandler("/static/js*//**").addResourceLocations("/resources/static/js/")
            .setCacheControl(CacheControl.maxAge(365, TimeUnit.DAYS))
            .resourceChain(false)
            .addResolver(new VersionResourceResolver().addContentVersionStrategy("/**"))
            .addTransformer(new CssLinkResourceTransformer());
}

@Bean
public ResourceUrlEncodingFilter resourceUrlEncodingFilter() {
    return new ResourceUrlEncodingFilter();
}
Run Code Online (Sandbox Code Playgroud)

我在脚本标签中使用表达式. 个:SRC = "@ {/资源/静态/ JS/companyList.js}"

ant*_*nyh 11

我没有代码就管理它,只有在 application.properties 中配置:

# Enable HTML5 application cache manifest rewriting.
spring.resources.chain.html-application-cache=true

# Enable the Spring Resource Handling chain. Disabled by default unless at least one strategy has been enabled.
spring.resources.chain.enabled=true
# Enable the content Version Strategy.
spring.resources.chain.strategy.content.enabled=true
# Comma-separated list of patterns to apply to the Version Strategy.
spring.resources.chain.strategy.content.paths=/**
Run Code Online (Sandbox Code Playgroud)

我不需要添加任何其他代码来获取 CSS 和 JS 的 URL 中的哈希版本。

  • 好建议,完全同意。https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html 和 https://github.com/spring-projects/spring-boot/blob/v2。 1.3.RELEASE/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ResourceProperties.java ? 这就是我能找到的所有内容,作为参考很有用,但没有解释每个设置的真正作用或如何组合它们。 (2认同)

Ole*_*han 6

1.创建LinkBuilder使用 Spring 的ThymeleafResourceUrlProvider创建版本化链接:

@Configuration
public class TemplateEngineConfig {
    @Autowired
    public void configureTemplateEngine(SpringTemplateEngine engine,
                                        ResourceUrlProvider urlProvider) {
        engine.setLinkBuilder(new VersioningLinkBuilder(urlProvider));
    }
}

class VersioningLinkBuilder extends StandardLinkBuilder {
    private final ResourceUrlProvider urlProvider;

    VersioningLinkBuilder(ResourceUrlProvider urlProvider) {
        this.urlProvider = urlProvider;
    }

    @Override
    public String processLink(IExpressionContext context, String link) {
        String lookedUpLink = urlProvider.getForLookupPath(link);
        if (lookedUpLink != null) {
            return super.processLink(context, lookedUpLink);
        } else {
            return super.processLink(context, link);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

2.使用百里香标签th:hrefth:src

<link th:href="@{/main.css}" rel="stylesheet" type="text/css"/>
<script th:src="@{/js/main.js}" type="text/javascript"></script>
Run Code Online (Sandbox Code Playgroud)

它将被转换为:

<link href="/main-0c362e5c8643b75ddf64940262b219f7.css" rel="stylesheet" type="text/css"/>
<script src="/js/main-c13acb86fa1012e27bbb01a7c4a9bf7f.js" type="text/javascript"></script>
Run Code Online (Sandbox Code Playgroud)

3.(可选)还建议添加浏览器缓存头。添加到您的application.properties

spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
spring.resources.cache.cachecontrol.max-age=365d
spring.resources.cache.cachecontrol.no-cache=false
spring.resources.cache.cachecontrol.no-store=false
spring.resources.cache.cachecontrol.cache-public=true
Run Code Online (Sandbox Code Playgroud)

或者,如果您使用application.yml

spring:
  resources:
    chain:
      strategy:
        content:
          enabled: true
          paths: /**
    cache:
      cachecontrol:
        max-age: 365d
        no-cache: false
        no-store: false
        cache-public: true
Run Code Online (Sandbox Code Playgroud)


Anı*_*ici 1

这是我的解决方案。我调试 Spring.ServletContextResource 类的源代码创建一个relativeRelative。然后检查资源是否存在。

资源位置:/resources/static/

路径:/static/css/login.css

pathToUse : /resources/static/static/css/login.css --> 该资源 url 不存在,因此返回 null。

ServletContextResource 类

@Override
public Resource createRelative(String relativePath) {
    String pathToUse = StringUtils.applyRelativePath(this.path, relativePath);
    return new ServletContextResource(this.servletContext, pathToUse);
}
Run Code Online (Sandbox Code Playgroud)

解决方案: 资源位置:/resources/static/

路径:/css/login.css

使用路径:/resources/static/css/login.css

现在我包含此格式。从路径中删除 /resources 。

th:src="@{/css/login.css}"

           @Override
           public void addResourceHandlers(final ResourceHandlerRegistry registry) 
           {

                registry.addResourceHandler("/theme*//**").addResourceLocations("/resources/static/")
                        .setCacheControl(CacheControl.maxAge(365, TimeUnit.DAYS))
                        .resourceChain(false)
                        .addResolver(new VersionResourceResolver().addContentVersionStrategy("/**"))
                        .addTransformer(new CssLinkResourceTransformer());
                registry.addResourceHandler("/css*//**").addResourceLocations("/resources/static/")
                        .setCacheControl(CacheControl.maxAge(365, TimeUnit.DAYS))
                        .resourceChain(false)
                        .addResolver(new VersionResourceResolver().addContentVersionStrategy("/**"))
                        .addTransformer(new CssLinkResourceTransformer());
                registry.addResourceHandler("/js*//**").addResourceLocations("/resources/static/")
                        .setCacheControl(CacheControl.maxAge(365, TimeUnit.DAYS))
                        .resourceChain(false)
                        .addResolver(new VersionResourceResolver().addContentVersionStrategy("/**"))
                        .addTransformer(new CssLinkResourceTransformer());

         @Override
         public void configure(final WebSecurity web) throws Exception {
 web.ignoring().antMatchers("/theme/**").antMatchers("/js/**").antMatchers("/css/**");
            }
Run Code Online (Sandbox Code Playgroud)