静态资源
此选项提供了一种便捷的方式来从基于 Resource 的位置列表中提供静态资源。
在下一个示例中,给定一个以 /resources
开头的请求,相对路径用于查找并服务位于 web 应用程序根目录下的 /public
或类路径下的 /static
中的静态资源。这些资源以一年的未来过期时间提供服务,以确保浏览器缓存的最大化利用,并减少浏览器发出的 HTTP 请求。Last-Modified
信息是从 Resource#lastModified
推导出来的,以便通过 "Last-Modified"
头支持 HTTP 条件请求。
以下列表展示了如何执行此操作:
- Java
- Kotlin
- Xml
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/public", "classpath:/static/")
.setCacheControl(CacheControl.maxAge(Duration.ofDays(365)));
}
}
@Configuration
class WebConfiguration : WebMvcConfigurer {
override fun addResourceHandlers(registry: ResourceHandlerRegistry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/public", "classpath:/static/")
.setCacheControl(CacheControl.maxAge(Duration.ofDays(365)))
}
}
<mvc:resources mapping="/resources/**" location="/public, classpath:/static/"
cache-period="31556926" />
另请参阅 静态资源的 HTTP 缓存支持。
资源处理器还支持一系列 ResourceResolver 实现和 ResourceTransformer 实现,您可以使用这些实现来创建一个用于处理优化资源的工具链。
你可以使用 VersionResourceResolver
来为资源 URL 添加版本号,版本号可以基于内容的 MD5 哈希值、固定的应用程序版本号或其他方式生成。ContentVersionStrategy
(基于 MD5 哈希值)是一个不错的选择——但在某些特殊情况下(例如与模块加载器一起使用的 JavaScript 资源)可能不适用。
以下示例展示了如何使用 VersionResourceResolver
:
- Java
- Kotlin
- Xml
@Configuration
public class VersionedConfiguration implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/public/")
.resourceChain(true)
.addResolver(new VersionResourceResolver().addContentVersionStrategy("/**"));
}
}
@Configuration
class VersionedConfiguration : WebMvcConfigurer {
override fun addResourceHandlers(registry: ResourceHandlerRegistry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/public/")
.resourceChain(true)
.addResolver(VersionResourceResolver().addContentVersionStrategy("/**"))
}
}
<mvc:resources mapping="/resources/**" location="/public/">
<mvc:resource-chain resource-cache="true">
<mvc:resolvers>
<mvc:version-resolver>
<mvc:content-version-strategy patterns="/**"/>
</mvc:version-resolver>
</mvc:resolvers>
</mvc:resource-chain>
</mvc:resources>
然后,你可以使用 ResourceUrlProvider
来重写 URL 并应用完整的解析器和转换器链——例如,插入版本号。MVC 配置提供了一个 ResourceUrlProvider
bean,以便它可以被注入到其他组件中。你还可以通过 ResourceUrlEncodingFilter
使重写对 Thymeleaf、JSP、FreeMarker 等依赖 HttpServletResponse#encodeURL
的 URL 标签透明。
请注意,当同时使用 EncodedResourceResolver
(例如,用于提供 gzip 或 brotli 编码的资源)和 VersionResourceResolver
时,必须按照此顺序注册它们。这样可以确保基于内容的版本始终基于未编码的文件可靠地计算。
对于 WebJars,推荐且最高效的使用方式是使用带版本的 URL,例如 /webjars/jquery/1.2.0/jquery.min.js
。Spring Boot 默认已经配置了相关资源的位置(或者可以通过 ResourceHandlerRegistry
手动配置),并且不需要添加 org.webjars:webjars-locator-core
依赖。
支持无版本号的 URL,如 /webjars/jquery/jquery.min.js
,这是通过 WebJarsResourceResolver
实现的,该解析器在类路径中存在 org.webjars:webjars-locator-core
库时会自动注册,但这可能会导致类路径扫描,从而减慢应用程序的启动速度。该解析器可以重写 URL 以包含 jar 的版本号,并且还可以匹配没有版本号的传入 URL —— 例如,将 /webjars/jquery/jquery.min.js
匹配为 /webjars/jquery/1.2.0/jquery.min.js
。
基于 ResourceHandlerRegistry
的 Java 配置提供了更多细粒度控制的选项,例如最后修改时间行为和优化的资源解析。