1.静态资源访问
1.1.静态资源目录
只要静态资源放在类路径下:/static
(or /public
or /resources
or /META-INF/resources
)
访问:当前项目根路径/ + 静态资源名
直接在浏览器中输入http://localhost:8080/ccc.png,就可以得到下面的
原理:静态资源映射是/**,即拦截所有请求
请求进来,先去找Controller看能不能处理。不能处理的所有请求又都交给静态资源处理器。静态资源也找不到,就报404
package com.company.boot.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @RequestMapping("/bbb.jpg") public String hello() { return "aaaa"; } }
可以看到localhost:8080/bbb.jpg先去找了controller,找到了,就返回了aaaa
1.2.静态资源的访问前缀
默认无前缀
想要给它一个指定前缀,需要配置
在application.yml中加入:
spring: mvc: static-path-pattern: /res/**
当前项目 + static-path-pattern + 静态资源名 = 静态资源文件下找
如果还像之前那样访问静态资源,localhost:8080/ccc.png,肯定是访问不到了
所有的请求都要加上前缀res
现在输入:localhost:8080/res/ccc.png
1.3 改变默认的静态资源路径
比如,我们希望以后所有的静态资源都放在abc文件夹下
在application.yml中添加static-locations: [classpath:/abc/]
spring: mvc: static-path-pattern: /res/** web: resources: static-locations: [classpath:/abc/]
1.4 webjar
自动映射 /webjars/**
https://www.webjars.org/
<dependency> <groupId>org.webjars</groupId> <artifactId>jquery</artifactId> <version>3.5.1</version> </dependency>
访问地址:http://localhost:8080/webjars/jquery/3.5.1/jquery.js 后面地址要按照依赖里面的包路径
这是引入了jquery静态资源的一个访问路径 ,了解即可,知道访问路径即可
2.欢迎页支持
- 静态资源路径下 index.html
- 可以配置静态资源路径
- 但是不可以配置静态资源访问前缀,否则导致index.html不能被默认访问
spring: # mvc: # static-path-pattern: /res/** 这个会导致welcome page功能失效 resources: static-locations: [classpath:/haha/]
这样直接在根目录下,就能加载index.html
- controller能出来/index
3.自定义 Favicon favicon.ico
放在静态资源目录下即可
spring: # mvc: # static-path-pattern: /res/** 这个会导致 Favicon 功能失效
4.静态资源配置原理
- SpringBoot启动默认加载 xxxAutoConfiguration类(自动配置类)
- SpringMVC功能的自动配置类 WebMvcAutoConfiguration,生效
@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 {}
- 给容器中配了什么
@Configuration(proxyBeanMethods = false) @Import(EnableWebMvcConfiguration.class) @EnableConfigurationProperties({ WebMvcProperties.class, ResourceProperties.class }) @Order(0) public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {}
EnableConfigurationProperties的作用就是开启WebMvcProperties,ResourceProperties
配置文件的相关属性和xxx进行了绑定。WebMvcProperties == spring.mvc、ResourceProperties == spring.resources
4.1 配置类只有一个有参构造器
//有参构造器所有参数的值都会从容器中确定 //ResourceProperties resourceProperties;获取和spring.resources绑定的所有的值的对象 //WebMvcProperties mvcProperties 获取和spring.mvc绑定的所有的值的对象 //ListableBeanFactory beanFactory Spring的beanFactory //HttpMessageConverters 找到所有的HttpMessageConverters //ResourceHandlerRegistrationCustomizer 找到 资源处理器的自定义器。========= //DispatcherServletPath //ServletRegistrationBean 给应用注册Servlet、Filter.... public WebMvcAutoConfigurationAdapter(ResourceProperties resourceProperties, WebMvcProperties mvcProperties, ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider, ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider, ObjectProvider<DispatcherServletPath> dispatcherServletPath, ObjectProvider<ServletRegistrationBean<?>> servletRegistrations) { this.resourceProperties = resourceProperties; this.mvcProperties = mvcProperties; this.beanFactory = beanFactory; this.messageConvertersProvider = messageConvertersProvider; this.resourceHandlerRegistrationCustomizer = resourceHandlerRegistrationCustomizerProvider.getIfAvailable(); this.dispatcherServletPath = dispatcherServletPath; this.servletRegistrations = servletRegistrations; }
4.2 资源处理的默认规则
@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的规则 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)); } }