12.静态资源访问
静态资源:例如js,css,图片等,放在类路径下的:/static (or /public or /resources or /META-INF/resources),可以直接访问
例如:http://localhost:8080/aa.jpg
例如:在resource文件下创建下面存放静态资源的文件夹,将静态资源放入其中可以直接访问
静态资源映射的是/**拦截所有请求,当请求过来时,如:http://localhost:8080/aa.jpg,
1.会先去动态请求里(Controller)找有没有能处理的
2.不能处理再去静态资源中(/static (or /public or /resources or /META-INF/resources))找有没有相关资源
3.都没有返回404
例子:
静态资源的访问前缀:
默认情况下,资源映射到/**,但是您可以使用spring.mvc.static-path-pattern属性对其进行调整。
例如,将所有资源重新定位到以下位置/resources/**可以实现:
spring.mvc.static-path-pattern=/resources/**
原因是:在配置拦截器时一般配置的是/**,这样会将静态资源也拦截住,所以可以使用该属性设置静态资源前缀,后续在设置拦截器时可以设置过滤静态资源的路径/**进行拦截
1.静态资源默认是没有前缀的,http://localhost:8080/aa.jpg可以直接访问到,
设置前缀:
spring:
mvc:
static-path-pattern: /res/**
这时:只能通过http://localhost:8080/res/aa.jpg才能访问到,
该标签只是在静态资源访问前加了个前缀,并不需要新建个res的文件夹,静态资源还是在原始的文件夹中存放
2.重新定义静态资源的路径(原始是在:1./static 2./public 3./resources 4./META-INF/resources)
spring.web.resources.static-locations
用法:
spring:
mvc:
static-path-pattern: /res/**
resources:
static-locations: [classpath:/haha/]
这时http://localhost:8080/res/aa.jpg,会去haha文件夹找该资源
欢迎页(和静态资源前缀有冲突,bug)
springboot支持欢迎页,在静态资源文件夹里放置index.html(必须是这个),如果找不到,他会寻找一个index模板。如果找到任何一个,它将自动用作应用程序的欢迎页面
即当输入:http://localhost:8080/可以定位到欢迎页
1.在springboot的配置文件中:
spring:
#配置了静态资源的前缀,这会影响springboot项目的所有静态资源访问,index.html也是,这时会出现bug:当访问http://localhost:8080/是无法访问到index页面的
mvc:
static-path-pattern: /res/**
resources:
static-locations: [classpath:/haha/]
但是如果此时把前缀注释掉:
spring:
# mvc:
# static-path-pattern: /res/**
resources:
static-locations: [classpath:/haha/]
输入:http://localhost:8080/是可以定位到欢迎页的
结论:当配置了静态资源的前缀时,欢迎页无法正常访问(http://localhost:8080/),但是(http://localhost:8080/res/index.html)可以访问到
静态资源的加载原理
在spring-boot-autoconfigure的jar包中:WebMvcAutoConfiguration里设置了静态资源的加载代码:
...
@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
...
public class WebMvcAutoConfiguration {
//1.内部类中开启webmvc的自动配置
@EnableConfigurationProperties({WebProperties.class})
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {
...
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
super.addResourceHandlers(registry);
//判断配置文件中的isAddMappings配置是否为false:
// 1.isAddMappings=false:等于关闭springboot的静态资源访问,所有静态资源不会加载到容器中,无法访问
// 2.isAddMappings=true:默认是true,开启springboot的静态资源访问
//例如:
// spring:
// resources:
// add-mappings: false
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
} else {
ServletContext servletContext = this.getServletContext();
//1.将webjars中的文件加载进容器:webjars是将js文件,jquery,css文件打成jar包
this.addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
//2.将自定义的静态资源加入容器:getStaticPathPattern是获取配置文件中静态资源配置的前缀
this.addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
registration.addResourceLocations(this.resourceProperties.getStaticLocations());
if (servletContext != null) {
registration.addResourceLocations(new Resource[]{new ServletContextResource(servletContext, "/")});
}
});
}
}
...
}
}
欢迎页的设置和加载
@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext, FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, this.getWelcomePage(), this.mvcProperties.getStaticPathPattern());
...
}
在上述实例化方法里:
WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders, ApplicationContext applicationContext, Resource welcomePage, String staticPathPattern) {
//发现这里的前缀是写死的:/**,index.html存在并且静态资源前缀是:/**(默认),则返回欢迎页:index.html,如果设置了静态资源前缀(配置文件中配置),这个条件不满足,所以会出冲突
if (welcomePage != null && "/**".equals(staticPathPattern)) {
logger.info("Adding welcome page: " + welcomePage);
this.setRootViewName("forward:index.html");
} else if (this.welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) {
logger.info("Adding welcome page template: index");
this.setRootViewName("index");
}
}
浏览器地址栏图标的选择(springboot2.2版本之前可以这么做)
将需要展示的图标,放入到静态资源文件夹里,名称改为:favicon.ico