这篇文章给大家介绍springboot2版本无法加载静态资源问题怎么解决,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。
前言
在学习springboot的过程中,发现无法引用静态资源。我使用的是springboot2.2.1版本。
追溯源码,终于解决。并记录下解决思路。
默认加载路径
首先得知道springboot默认加载得资源路径是什么。
首先我们看WebMvcAutoConfiguration这个类。里面有一个方法叫做addResourceHandlers()
@Configuration(proxyBeanMethods = false)@ConditionalOnWebApplication(type = Type.SERVLET)@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class })public class WebMvcAutoConfiguration {
@Override public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return; }
Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
//所有 /webjars/** ,都去 classpath:/META-INF/resources/webjars/ 找资源 if (!registry.hasMappingForPattern("/webjars/**")) { customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**") .addResourceLocations("classpath:/META-INF/resources/webjars/") .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl)); }
//静态资源文件夹映射 String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) { customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern) .addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations())) .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl)); } }}
首先springboot会将我们classpath:/META-INF/resources/webjars/路径下的文件映射为/webjars/**
然后再一个if判断进行静态资源文件夹映射,首先判断我们是否以使用 "/**" 做映射
如果没有,则将"/**" 访问当前项目的任何资源,都去(如下静态资源的文件夹)找映射
"classpath:/META‐INF/resources/","classpath:/resources/","classpath:/static/","classpath:/public/""/":当前项目的根路径
什么意思呢?举一个例子,就是说默认情况下我们假如我们调用 http://localhost:8080/a.json
Springboot就会从上面得这几个路径下去找a.json这个文件。
问题所在
源码也是如同猜想得这样,那为什么我的代码中,直接访问静态资源却无法做映射呢?
我们再仔细看看WebMvcAutoConfiguration这个类。在其头上有一个这个注解:
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
卧槽,瞬间恍然大悟。在我得配置文件中:
@Configurationpublic class MyMVCConfig extends WebMvcConfigurationSupport{ ...}
继承了WebMvcConfigurationSupport这个类,使得springboot的自动装配失效了。因为@ConditionalOnMissingBean这个注解得作用就是,当容器中不存在这个类,如下得代码才有作用。
为什么会这样设计呢?
因为有时候我们得项目并不希望springboot给我们自动装配。希望完全由我们自己来配置自己来掌握。
要想达到这个效果,springboot给我们提供了一个更为简洁得方式。
@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)@Documented@Import(DelegatingWebMvcConfiguration.class)public @interface EnableWebMvc {}
@EnableWebMvc注解会导入DelegatingWebMvcConfiguration.clss
而DelegatingWebMvcConfiguration又继承了WebMvcConfigurationSupport
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
所以当我们加上@EnableWebMvc也会有同样得效果且简洁。
自定义配置资源映射
springboot当然也支持我们个性化得指定映射路径,我总结了如下几个方式:
配置类
@Configurationpublic class MyMVCConfig extends WebMvcConfigurationSupport{ @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/"); }}
上面的意思就是:将所有/static下得文件全部映射到/static/**
配置项
在application.properties文件中加上如下配置项
spring.mvc.static-path-pattern=/**spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/, classpath:/static/,classpath:/public/
spring.mvc.static-path-pattern=/**:表示所有的访问都经过静态资源路径;
spring.resources.static-locations:在这里配置静态资源路径。
关于springboot2版本无法加载静态资源问题怎么解决就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。