SpringBoot添加对静态文件css/html/jpg等的直接访问的支持

时间:2021-03-14 13:05:13

请直接看四、解决对策,希望本文解决你的问题

------正文------

一、背景

现在网上大多讨论的是对SpringBoot使用由freemarker等模板引擎渲染出的html网页的静态访问的支持。但是对于一个前后端分离的项目,比如前端使用vue、React等写,后端使用Spring家族技术等,往往开发者选择将前端开发的网页通过webpack直接打包成含组成网页的静态文件的文件夹   然后交到后端同学手中。比如在/dist下:

SpringBoot添加对静态文件css/html/jpg等的直接访问的支持

图1       前端打包的静态文件

 

二、问题产生

一般而言SpringBoot中默认开启支持浏览器直接访问这些静态文件的,只要你放在诸如src/main/resources/下的static等就可以使用浏览器访问。但是有可能像我一样无法访问,出现类似404的问题(There was an unexpected error (type=Not Found, status=404).):

SpringBoot添加对静态文件css/html/jpg等的直接访问的支持

图2      浏览器无法直接访问静态资源

 

三、问题原因猜想

这里分析有误的,请指出,谢谢】浏览器输入http://localhost:8080/1.png  (1.png在/src/main/resources/static/1.png),无法访问,查看Idea的控制台输出:

SpringBoot添加对静态文件css/html/jpg等的直接访问的支持

图3     Idea控制台输出

意思是找不到处理我的静态文件[1.png]的dispatcherServlet,进一步搜索,大概意思是静态资源无法映射,这让我很好奇:静态资源不是默认有映射的吗,为什么需要交给servlet来处理?难道需要把"1.png"和各个RestController中的接口方法的@RequestMapping的值比对吗?后来在Stack Overflow上发现是默认的映射出了问题。

前面提到过,SpringBoot默认会帮你配置对静态文件访问的映射,但是如果你通过某种直接或者其它间接的方式使用了@EnableWebMvc,意思是你想完全地进行web配置,那么Spring就会忽略默认的配置信息,去寻找相应的你的设置文件。如果你没有设置,就会出现上面这个问题了。

虽然我不知道我哪里使用了@EnableWebMvc,但是顺着这个思路,发现能够解决这个问题。这个通过结果猜想过程的方法不严谨,因此如果有理解错误,请大家指出,一是矫正我的错误,二是不想让看我文章的读者被我误导,谢谢。

 

四、解决对策

解决方法是配置WebMvcXXX(多说一句WebMvcConfigurerAdapter在Spring新版本已经过时,因此再看相应的解决方案请慎重)比如新建一个文件WebConfiguration.java,然后码上如下代码:

 1 import org.springframework.context.annotation.Configuration;
 2 import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
 3 import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
 4 import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
 5 
 6 @Configuration
 7 public class WebConfiguration extends WebMvcConfigurationSupport {
 8 
 9     @Override
10     public void addResourceHandlers(ResourceHandlerRegistry registry){
11         registry.addResourceHandler("/**")
12                 .addResourceLocations("classpath:/static/");
13     }
14 
15     @Override
16     public void addViewControllers(ViewControllerRegistry registry) {
17         registry.addViewController("/").setViewName("forward:/index.html");
18     }
19 }

注意:15-18是将"/"映射到"/index.html"去,如果没有这个需求可以去掉。

 

如果没有解决你的问题,请不要放弃,继续在互联网上探索了。

 

五、引用及致谢

我只是知识的搬运工,这篇文章离不开他们:

[1] https://*.com/questions/41691770/spring-boot-unabe-to-serve-static-image-from-resource-folder

[2] https://*.com/questions/27381781/java-spring-boot-how-to-map-my-app-root-to-index-html

  以及其它参考过的网页