Spring Boot 静态资源访问原理解析
1 使用properties配置
应该说 spring.mvc.static-path-pattern 和 spring.resources.static-locations(高版本 spring.web.resources.static-locations)这两属性是成对使用的。spring.mvc.static-path-pattern代表的是一个Ant Path路径,例如resources/**,表示当你的路径中存在resources/的时候才会处理请求。比如我们访问“http://localhost:8080/resources/xxx.js”时,很显然,springboot逻辑中会根据模式匹配对url进行匹配,匹配命中后,是如何再定位到具体的资源的呢?这时候spring.resources.static-locations的配置就起作用了。
忘记说了,在springboot中spring.mvc.static-path-pattern的默认值是/,spring.web.resources.static-locations的默认值是classpath:/static,classpath:/public,classpath:/resources,classpath:/META-INF/resources,servlet context:/,springboot中相关的ResourceHttpRequestHandler就会去spring.resources.static-locations配置的所有路径中寻找资源文件。
所以我之前才说spring.mvc.static-path-pattern 和 spring.resources.static-locations这两属性是成对使用的。
或者yml
spring
mvc:
static-path-pattern: /static/**
web:
resources:
static-locations: classpath:/static
2 springboot默认静态资源处理
调试过程中,通过查看 org.springframework.web.servlet.DispatcherServlet中的handlerMappings变量,我们发现有一个很显眼的 resourceHandlerMapping ,这个是springboot为我们提供的一个默认的静态资源handler,通过全文搜索发现出现在org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport这个类中,也就是这个类包含了@EnableWebMvc注解中的大多数功能,更多的扩展功能请参考org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration。
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/index").setViewName("index");
}
/**
* 这是原来就写的用来解决跨域的,不过好像没有用(狗头保命)
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
// .allowedOrigins("*")
.allowedOriginPatterns("*")
.allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
.allowCredentials(true)
.allowedHeaders("*")
.maxAge(3600);
}
/**
* 添加资源映射,允许静态资源的访问
* addResourceHandler() 拦截的请求路径
* addResourceLocations() 真实的文件地址:classpath:xxxxxxx
* 简单来说就是把位于哪些位置下的具体某些资源(一个或多个,下面的代码正好是案例)进行放行
* static下的所有资源,swagger-ui.html单个资源
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/static/**")
.addResourceLocations("classpath:/static/")
.setCacheControl(CacheControl.maxAge(1, TimeUnit.HOURS).cachePublic())
.setCachePeriod(604800); //一周
}
}
```