静态资源

此选项提供了一种方便的方式,可以从基于Resource的位置列表中提供静态资源。

在下一个示例中,对于以/resources开头的请求,使用相对路径来查找并提供相对于Web应用程序根目录下的/public或类路径下的/static的静态资源。这些资源将以一年后的过期时间提供,以确保浏览器缓存的最大利用,并减少浏览器发出的HTTP请求。Last-Modified信息是从Resource#lastModified推断出来的,以便支持带有"Last-Modified"头的HTTP条件请求。

以下清单显示了如何在Java配置中执行此操作:

  • Java

  • Kotlin

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		registry.addResourceHandler("/resources/**")
				.addResourceLocations("/public", "classpath:/static/")
				.setCacheControl(CacheControl.maxAge(Duration.ofDays(365)));
	}
}
@Configuration
@EnableWebMvc
class WebConfig : WebMvcConfigurer {

	override fun addResourceHandlers(registry: ResourceHandlerRegistry) {
		registry.addResourceHandler("/resources/**")
				.addResourceLocations("/public", "classpath:/static/")
				.setCacheControl(CacheControl.maxAge(Duration.ofDays(365)))
	}
}

以下示例显示了如何在XML中实现相同的配置:

<mvc:resources mapping="/resources/**"
	location="/public, classpath:/static/"
	cache-period="31556926" />

资源处理程序还支持一系列ResourceResolver实现和ResourceTransformer实现,您可以使用它们创建用于处理优化资源的工具链。

您可以使用VersionResourceResolver来基于内容计算的MD5哈希、固定应用程序版本或其他内容生成带版本的资源URL。使用ContentVersionStrategy(MD5哈希)是一个不错的选择,但也有一些值得注意的例外情况,比如与模块加载器一起使用的JavaScript资源。

以下示例显示了如何在Java配置中使用VersionResourceResolver

  • Java

  • Kotlin

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		registry.addResourceHandler("/resources/**")
				.addResourceLocations("/public/")
				.resourceChain(true)
				.addResolver(new VersionResourceResolver().addContentVersionStrategy("/**"));
	}
}
@Configuration
@EnableWebMvc
class WebConfig : WebMvcConfigurer {

	override fun addResourceHandlers(registry: ResourceHandlerRegistry) {
		registry.addResourceHandler("/resources/**")
				.addResourceLocations("/public/")
				.resourceChain(true)
				.addResolver(VersionResourceResolver().addContentVersionStrategy("/**"))
	}
}

以下示例显示了如何在XML中实现相同的配置:

<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,因此可以将其注入到其他bean中。您还可以通过ResourceUrlEncodingFilter使重写对于Thymeleaf、JSP、FreeMarker等依赖于HttpServletResponse#encodeURL的URL标签变得透明。

请注意,当同时使用EncodedResourceResolver(例如用于提供经过gzip或brotli编码的资源)和VersionResourceResolver时,必须按照这个顺序注册它们。这样可以确保始终可靠地基于未编码文件计算基于内容的版本。

对于WebJars,像/webjars/jquery/1.2.0/jquery.min.js这样的带版本的URL是推荐且最有效的使用方式。相关的资源位置在Spring Boot中已经配置好(或者可以通过ResourceHandlerRegistry手动配置),不需要添加org.webjars:webjars-locator-core依赖。

通过WebJarsResourceResolver支持像/webjars/jquery/jquery.min.js这样无版本的URL,当类路径中存在org.webjars:webjars-locator-core库时,该解析器会自动注册,但这可能会减慢应用程序启动速度。该解析器可以重写URL以包含jar的版本,并且还可以匹配不带版本的传入URL,例如从/webjars/jquery/jquery.min.js/webjars/jquery/1.2.0/jquery.min.js

基于ResourceHandlerRegistry的Java配置提供了更多细粒度控制选项,例如最后修改行为和优化资源解析。