SpringBoot静态资源、welcome page配置解析

1,543 阅读9分钟

SpringBoot-Web开发

官方网址:docs.spring.io/spring-boot…

image.png

Springboot是框架的框架,在web开发这一块就对我们的springmvc做了一系列的底层配置

1、SpringMVC自动配置概览

Spring Web MVC 框架(通常称为“Spring MVC”)是一个丰富的“model view controller ”Web 框架。Spring MVC 允许您创建特殊的@Controller@RestController来处理传入的 HTTP 请求。控制器中的方法通过使用@RequestMapping注解映射到 HTTP。

Spring Boot 为 Spring MVC 提供了自动配置,适用于大多数应用程序。及大多场景我们都无需自定义配置,自动配置在 Spring 的默认值之上添加了以下特性:

  • Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans:包括内容协商视图解析器和BeanName视图解析器
  • Support for serving static resources, including support for WebJars (covered later in this document)):支持提供静态资源,包括对 WebJars 的支持
  • Automatic registration of Converter, GenericConverter, and Formatter beans:自动注册ConverterGenericConverterFormatter
  • Support for HttpMessageConverters (covered later in this document):支持 HttpMessageConverters (后来我们配合内容协商理解原理)
  • Automatic registration of MessageCodesResolver (covered later in this document):自动注册 MessageCodesResolver (国际化用)
  • Static index.html support:静态index.html 页支持
  • Custom Favicon support (covered later in this document):自定义 Favicon
  • Automatic use of a ConfigurableWebBindingInitializer bean (covered later in this document):自动使用 ConfigurableWebBindingInitializer,(DataBinder负责将请求数据绑定到JavaBean上)

如果您想保留那些 Spring Boot MVC 自定义并进行更多MVC 自定义(拦截器、格式化程序、视图控制器和其他功能),您可以不用@EnableWebMvc注解。使用 @Configuration + WebMvcConfigurer 自定义规则

如果您想提供、 或的自定义实例RequestMappingHandlerMapping,并且仍然保留 Spring Boot MVC 自定义,则可以声明 WebMvcRegistrations 改变默认底层组件

如果你想完全控制 Spring MVC,你可以使用 @EnableWebMvc+@Configuration+DelegatingWebMvcConfiguration 全面接管SpringMVC

2、静态资源访问规则与定制化

2.1、概述

默认情况下,Spring Boot 从类路径resource中名为/static(或/public/resources/META-INF/resources)的目录或从ServletContext.的根目录提供静态内容,因此只要这些路径里面有我们的静态资源[图片、css资源],我们就能通过浏览器发起请求获得静态资源:访问 当前项目根路径/ + 静态资源名。举例如下:

2.2、演示

初始化一个SpringBoot工程

image.png

工程创建好以后,这里我们分别创建static[本来就有]、public、resources、META-INF/resources目录,并且放一些图片在每个目录下进行演示:如下图:

image.png

启动项目,浏览器地址输入:http://localhost:8080/1.jpg 即可,其他静态资源也是一样

image.png

静态资源访问原理:为什么输入当前项目根路径/ +静态资源名就能访问到静态资源,比如这里我们用浏览器发起一个和当前访问静态资源相同的动态请请求,如下:

这里我们新建了一个Controller

image.png

请问:当我浏览器发起请求:http://localhost:8080/1.jpg,这时候由于请求名恰好和其中一个静态资源名相同,请问浏览器返回什么?是找静态资源还是返回我们的动态请求?通过下面的答案可以知道:是动态资源

image.png

因此原理总结:默认情况下,这些静态资源被映射到/**上,也就是拦截所有请求,于是一个请求进来,先去找Controller看能不能处理,能处理就自己处理,不能处理的所有请求又都交给静态资源处理器,如果静态资源也找不到则响应404页面。

你也可以改变默认的静态资源访问路径/**,可以在配置文件中通过spring.mvc.static-path-pattern进行修改,例如,将所有资源重新分配到/resources/**,即加个访问前缀【加个前缀就是防止拦截器将所有资源都拦截了,放行以指定路径开头的资源:可以实现如下:下面展示了两种配置文件的配置方式,一般用Yaml的方式进行配置

image.png

因此这种时候静态资源的访问路径为:当前项目 + static-path-pattern + 静态资源名 = 静态资源文件夹下找,比如:http://localhost:8080/resources/1.jpg ,重新启动项目进行访问:

image.png

除了上面改变静态资源访问路径,官网还提出了另外一个观点:您还可以使用spring.web.resources.static-locations定制静态资源的位置【默认是在之前提出的类路径下的4个目录下】。如下:这里指定类路径下的picture文件夹为静态资源的访问路径

image.png

于是访问该picture文件夹下的1.jpg可以访问到:但是访问原先4个目录里面的文件不能访问了

image.png

注意一些小问题:idea有缓存,如果上述结果不能实现,重启idea。

2.3、webjars下的静态资源访问

除了上面提到的“标准”静态资源位置外,还有一个特殊情况是关于webjar内容的。任何路径在/webjars/**中的资源都是从jar文件提供的,它们被打包为webjar格式。

Webjar:可用jar方式添加css,js等资源文件,

官网:www.webjars.org/, 例如,添加jquery依赖,可以看到这些都是前端框架的jar包,我们直接复制一个jquery的maven坐标,然后粘贴到pom文件中

image.png

访问jquery资源的地址:http://localhost:8080/webjars/jquery/3.6.0/jquery.js 后面地址要按照依赖里面的包路径,如下: 不需要加resources

image.png

结果:

image.png

经过测试,这三个目录的优先级是resources最高,static第二,public最低。一般我们存放静态资源都是这三个目录,使用最多的是static

3、welcome page欢迎页

3.1、概述

官方文档:Spring Boot既支持静态欢迎页面index.html,也支持模板欢迎页面。它首先在配置的静态资源的路径中查找index.html文件。如果没有找到,则查找一个index模板[template下]。如果找到其中一个,它将自动用作应用程序的欢迎页面。

补充:template文件夹下的index.html必须通过Controller访问,详情参考模板引擎thymeleaf

3.2、演示

静态资源路径picture下放置欢迎页: index.html。首先,我们由于上述自定义了静态资源路径picture,所以这里在这下面新建index.html页面

image.png

但是启动服务器,访问项目根路径根本不能出现欢迎页,报404错误 :

image.png

于是我们换一种方式,首先注销所有yaml配置文件的内容,一切都恢复默认资源路径进行,比如将index首页放到static文件夹下【还是不行肯定是浏览器和Idea的问题,全部重启】

image.png

所以只要把文件放到静态资源路径即可,但是我们上面的picture为什么不行呢?猜想有可能是我们配置了前缀rsources,记住{默认页是不需要前缀访问的,不然就不叫默认页了},所以这里我们把它注销在尝试,这次就可以了

image.png

因此得出结论:这种静态资源路径下放index.html的方式,我们在操作上可以配置静态资源路径,但是不可以配置静态资源的访问前缀。否则导致 index.html不能被默认访问

4、自定义Favicon

favicon指网页标签上的小图标:如下图所示,随便找个网站下一个图标下来

image.png

favicon.ico 放在静态资源目录下即可,建议以后还是用默认的静态资源目录,访问前缀还是配上

image.png

启动成功

image.png

5、web场景-【源码分析】-静态资源访问原理

首先,SpringBoot启动就会在系统配置文件进行默认加载 xxxAutoConfiguration 类(自动配置类),其中SpringMVC功能的自动配置类是WebMvcAutoConfiguration[servlet包下],静态资源的配置是在WebMvcAutoConfiguration这个自动配置类中配置的,按照惯例首先看这个配置类是否生效:

1、全部满足条件装配规则,所以该配置类生效:

image.png

2、因此下一步我们来看导入了这个配置类,它给容器配置了什么内容:往下继续查看该配置类的源码[这里只挑选几个重要的]:

image.png

这些都是SpringMVC给容器中基本的配置,不是本节的重点

3、继续往下查看源码:会发现一个静态的内部类,从头部注解可知,它也是一个配置类,因此我们又来研究它干了什么。重点查看这行注解的代码:@EnableConfigurationProperties({WebProperties.class}),表明会把该注解所注明的配置文件和一些类的相关属性进行了绑定:

image.png

可以发现,里面有一个WebProperties文件,我们进入它的源码,如下:可以发现,它是与我们的以spring.web为前缀的相关属性进行了绑定。

image.png

注意:这个内部的配置类只有一个有参构造器,表明有参构造器的所有参数的值都会从容器中确定:有参构造如下

image.png

  • ResourceProperties resourceProperties;获取和spring.resources绑定的所有的值的对象
  • WebMvcProperties mvcProperties 获取和spring.mvc绑定的所有的值的对象
  • WebProperties webProperties 获取和spring.web绑定的所有的值的对象
  • ListableBeanFactory beanFactory 获取Spring的beanFactory :容器
  • ResourceHandlerRegistrationCustomizer 找到资源处理器的自定义器

对于上述这些东西,这个配置类已经从容器中通过这个构造器拿到了,继续往下看源码,直到找到下面这个方法,这个方法是添加资源处理器,这就是静态资源处理的默认规则

image.png

首先,if (!this.resourceProperties.isAddMappings()) 这个代码里面的resourceProperties就是我们通过构造器在容器中已经配好的,isAddMappings()方法通过查看源码最终会返回一个bool类型的属性addmappping,因此如果该属性在yaml配置文件中配置成了flase[默认是true],则下面的webjars这些代码不生效,意味着我们可以同过配置属性addmappping禁止所有静态资源规则,[该属性是和spring.resources进行了绑定]如下:

image.png

这时候,于是我们再次访问静态资源[如四个目录里面的照片]就不能访问了,出现404,下面我们将该属性配置成默认的true,则下面的webjars这些代码生效

image.png

可以看出,addResourceHandler()方法是关键,该方法的具体实现往下翻即可找到

image.png

对应的在yaml配置文件中进行设置cache缓存时间

image.png

进入period,发现是以s为单位的,即静态资源默认可以存多少s

image.png

因此,该方法内部实现了一个缓存策略,然后按照设置的访问时间就开始进行我们的webjars路径的资源访问设置:

这就定义了以前访问jquery时候的路径是什么

image.png

再继续看该方法下的下图标出的源码,这就是静态资源我们4个默认目录的值

image.png

进入getStaticLoction方法

image.png

欢迎页的处理规则:该源码还是在该配置类里面

image.png

这构造方法内的代码也解释了web场景-welcome与favicon功能中配置static-path-pattern了,welcome页面和小图标失效的问题。