使用Spring MVC进行资源版本控制

提供静态资源时,通常的做法是将某种版本信息附加到资源URL。 这使浏览器可以无限期地缓存资源。 每当资源的内容更改时,URL中的版本信息也会更改。 更新的URL会强制客户端浏览器放弃缓存的资源,并从服务器重新加载最新的资源版本。

使用Spring,只需两个简单的步骤即可配置版本化的资源URL。 在这篇文章中,我们将看到它是如何工作的。

提供版本化网址

首先,我们需要告诉Spring应该通过版本化的URL访问资源。 这是在资源处理程序MVC配置中完成的:

@Configuration
public class MvcApplication extends WebMvcConfigurerAdapter {

  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
    VersionResourceResolver versionResourceResolver = new VersionResourceResolver()
        .addVersionStrategy(new ContentVersionStrategy(), "/**");

    registry.addResourceHandler("/javascript/*.js")
        .addResourceLocations("classpath:/static/")
        .setCachePeriod(60 * 60 * 24 * 365) /* one year */
        .resourceChain(true)
        .addResolver(versionResourceResolver);
  }

  ...
}

在这里,我们为位于类路径内名为static的文件夹中JavaScript文件创建资源处理程序。 这些JavaScript文件的缓存时间设置为一年。 重要的部分是VersionResourceResolver ,它支持带有版本信息的资源URL。 VersionStrategy用于获取资源的实际版本。

在此示例中,我们使用ContentVersionStrategy 。 此VersionStrategy实现从资源的内容计算MD5哈希并将其附加到文件名。

例如:假设我们在classpath:/ static /目录中有一个JavaScript文件test.js。 test.js的MD5哈希为69ea0cf3b5941340f06ea65583193168。

现在,我们可以将请求发送至:

/javascript/test-69ea0cf3b5941340f06ea65583193168.js

它将解析为classpath:/static/test.js。

请注意,仍然可以在没有MD5哈希的情况下请求资源。 因此,此请求也适用:

/javascript/test.js

另一个VersionStrategy实现是FixedVersionStrategy 。 FixedVersionStrategy使用固定版本字符串作为前缀添加到资源路径。

例如:

/v1.2.3/javascript/test.js

生成版本化的URL

现在,我们需要确保应用程序生成的资源URL包含MD5哈希。

一种解决方法是使用ResourceUrlProvider 。 使用ResourceUrlProvider,可以将资源URL(例如/javascript/test.js)转换为版本化的URL(例如/javascript/test-69ea0cf3b5941340f06ea65583193168.js)。 使用MVC配置会自动声明ID为mvcResourceUrlProvider的ResourceUrlProvider bean。

如果您将Thymeleaf用作模板引擎,则可以使用@bean语法直接从模板访问ResourceUrlProvider bean。

例如:

<script type="application/javascript"
        th:src="${@mvcResourceUrlProvider.getForLookupPath('/javascript/test.js')}">
</script>

如果使用的模板引擎不能直接访问Spring Bean,则可以将ResourceUrlProvider Bean添加到模型属性中。 使用ControllerAdvice ,可能看起来像这样:

@ControllerAdvice
public class ResourceUrlAdvice {

  @Inject
  ResourceUrlProvider resourceUrlProvider;

  @ModelAttribute("urls")
  public ResourceUrlProvider urls() {
    return this.resourceUrlProvider;
  }
}

然后,在视图内部,我们可以使用urls模型属性访问ResourceUrlProvider:

<script type="application/javascript" 
        th:src="${urls.getForLookupPath('/javascript/test.js')}">
</script>

此方法应与所有支持方法调用的模板引擎一起使用。

生成版本化URL的另一种方法是使用ResourceUrlEncodingFilter 。 这是一个Servlet筛选器,它重写HttpServletResponse.encodeURL()方法以生成版本化的资源URL。

要使用ResourceUrlEncodingFilter,我们只需要向配置类中添加一个额外的bean:

@SpringBootApplication
public class MvcApplication extends WebMvcConfigurerAdapter {

  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
    // same as before ..
  }

  @Bean
  public ResourceUrlEncodingFilter resourceUrlEncodingFilter() {
    return new ResourceUrlEncodingFilter();
  }

  ...
}

如果您使用的模板引擎调用了响应encodeURL()方法,则版本信息将自动添加到URL。 这将适用于JSP,Thymeleaf,FreeMarker和Velocity。

例如:通过Thymeleaf,我们可以使用标准的@ {..}语法来创建URL:

<script type="application/javascript" th:src="@{/javascript/test.js}"></script>

这将导致:

<script type="application/javascript" 
        src="/javascript/test-69ea0cf3b5941340f06ea65583193168.js">
</script>

摘要

将版本信息添加到资源URL是最大化浏览器缓存的常见做法。 使用Spring,我们只需要定义一个VersionResourceResolver和一个VersionStrategy即可提供版本化的URL。 在模板引擎内部生成版本化URL的最简单方法是使用ResourceUrlEncodingFilter。

如果标准的VersionStrategy实现不符合您的要求,则可以创建我们自己的VersionStrategy实现。

  • 您可以在GitHub上找到完整的示例源代码。

翻译自: https://www.javacodegeeks.com/2015/09/resource-versioning-with-spring-mvc.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值