SpringBoot 静态资源处理


 

springboot源码版本 2.3.12.RELEASE

springboot给webmvc提供的自动配置类是 WebMvcAutoConfiguration,这篇博文中涉及到的源码都是这个类中的。

 

主要提供的bean

使用 @Bean 提供了一些webmvc常用的bean

  • ViewResolver 视图解析器
  • RequestContextFilter 过滤器
  • RequestMappingHandlerAdapter 处理器适配器
  • RequestMappingHandlerMapping 处理器映射器
  • WelcomePageHandlerMapping 首页设置
  • Validator 参数校验

 

静态资源的路径映射

addResourceHandlers()

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
	if (!this.resourceProperties.isAddMappings()) {
		logger.debug("Default resource handling disabled");
		return;
	}
	addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
	addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(),
			this.resourceProperties.getStaticLocations());
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
	if (!this.resourceProperties.isAddMappings()) {
		logger.debug("Default resource handling disabled");
		return;
	}
	//映射webjar
	addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
	//映射其它静态资源
	addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
		//关注 this.resourceProperties.getStaticLocations()
		registration.addResourceLocations(this.resourceProperties.getStaticLocations());
		if (this.servletContext != null) {
			ServletContextResource resource = new ServletContextResource(this.servletContext, SERVLET_LOCATION);
			registration.addResourceLocations(resource);
		}
	});
}

主要做了2件事

  • 映射webjar:将 classpath:/META-INF/resources/webjars/ 下的资源路径映射为 /webjars/**
  • 映射其它静态资源:将指定位置下的静态资源路径映射为 /**

 

静态资源的位置

沿着 this.resourceProperties.getStaticLocations() 定位到 ResourceProperties,这个类是web资源的配置类

//对应yml中的 spring.resources 配置
@ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)
public class ResourceProperties {

	静态资源的默认位置
	private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",
			"classpath:/resources/", "classpath:/static/", "classpath:/public/" };

	//指定静态资源位置,默认值为上面的常量
	private String[] staticLocations = CLASSPATH_RESOURCE_LOCATIONS;

	//...

}

可以在yml中用 spring.resources.static-locations 指定静态资源位置,未指定时的静态资源默认位置为

  • classpath:/META-INF/resources/
  • classpath:/resources/
  • classpath:/static/
  • classpath:/public/

即 classpath 下的4个文件夹。以上顺序也是静态资源的查找顺序,比如 static、public 下都有一个index.html,映射 /index.html 是映射到 static 中的 index.html,找到第一个即终止,查找首页同理。

springboot自带的resources文件夹本身就是classpath的一部分,当做classpath根目录看待。通常是在自带的resources文件下,新建 static 或public 文件夹来存放静态资源。

 

静态资源的访问路径

spring.resources.static-locations 指定的静态资源位置会被映射为 /** 即静态资源的根目录。

通常使用默认位置的 classpath:/static/classpath:/public/ ,在自带的resources文件夹下,新建 static 或 public 文件夹来存放静态资源。

示例:把 jquery.js 放在 static/js/ 下,映射路径直接取 static | public 后面的部分

<!--html引入路径-->
<script src="js/jquery.min.js"></script>
#浏览器可直接访问静态资源
http://localhost:8080/{context-path}/js/jquery.js

 

webjars的使用

webjars 顾名思义,以jar包形式引入web静态资源依赖,此处以引入jq为例

<dependency>
	<!-- groupid是org.webjars,不能是其它的 -->
    <groupId>org.webjars</groupId>
    <artifactId>jquery</artifactId>
    <version>3.6.0</version>
</dependency>

在这里插入图片描述
 

访问路径是 resources 后面的部分 webjars/jquery/3.6.0/jquery.js,一般是 webjars/{artifactId}/{version}/…

<!-- html引入-->
<script src="webjars/jquery/3.6.0/jquery.js"></script>
#浏览器直接访问
http://localhost:8080/{context-path}/webjars/jquery/3.6.0/jquery.js

 

首页映射

welcomePageHandlerMapping()

@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,
		FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
	WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(
			//getWelcomePage()获取首页
			new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(),
			this.mvcProperties.getStaticPathPattern());
	welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));
	welcomePageHandlerMapping.setCorsConfigurations(getCorsConfigurations());
	return welcomePageHandlerMapping;
}


private Resource getWelcomePage() {
	//遍历静态资源的所有位置
	for (String location : this.resourceProperties.getStaticLocations()) {
		//调用getIndexHtml()查找首页
		Resource indexHtml = getIndexHtml(location);
		if (indexHtml != null) {
			return indexHtml;
		}
	}
	//如果在静态资源位置找不到,则在 ServletContext 中找
	ServletContext servletContext = getServletContext();
	if (servletContext != null) {
		//调用getIndexHtml()查找首页
		return getIndexHtml(new ServletContextResource(servletContext, SERVLET_LOCATION));
	}
	return null;
}


private Resource getIndexHtml(String location) {
	return getIndexHtml(this.resourceLoader.getResource(location));
}

private Resource getIndexHtml(Resource location) {
	try {
		//把 index.html 作为首页
		Resource resource = location.createRelative("index.html");
		if (resource.exists() && (resource.getURL() != null)) {
			return resource;
		}
	}
	catch (Exception ex) {
	}
	return null;
}

先在静态资源位置中查找 index.html 文件,把查找到的第一个 index.html 文件作为首页,映射为 /**,访问 http://localhost:8080/{context-path} 时显示该页面;如果找不到,会在 ServletContext 中继续找。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值