1、静态资源访问
1.1、静态资源目录
当前项目类路径下:called /static
(or /public
or /resources
or /META-INF/resources
访问:当前项目根路径/+静态资源名
原理:静态映射/**
请求进来先去找Controller看能不能处理,不能处理的请求则会交给静态资源处理器,静态资源能找到则访问,如果找不到则为404
2、静态资源访问前缀
默认无前缀,如果要自定义的话在application.yml中做以下操作:
spring:
mvc:
static-path-pattern: /res/**
#static-path-pattern: /** 默认
访问则会成为:当前项目+static-path-pattern+静态资源名=静态资源文件夹下找2.3、webjar
2.3、webjar
自动映射: https://www.webjars.org/
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.5.1</version>
</dependency>
引入pom链接,默认访问路径/webjars/**,下面是一个访问的例子:
访问地址: http://localhost:8080/webjars/jquery/3.5.1/jquery.js webjars/后面的地址要按照依赖中的包路径来
2.4、欢迎页支持的几种方式
静态资源路径下 index.html
- 可以配置静态资源路径
- 但是不能配置静态资源访问前缀,否则将导致index.html不能被默认访问
spring:
#mvc:
#static-path-pattern: /res/** #改变静态资源前缀路径
#static-path-pattern: /** 默认
web:
resources:
static-locations: [classpath:/haha/] #改变静态资源默认文件夹位置
-
2.5、自定义Favicon网页标签图标
#spring:
# mvc:
# static-path-pattern: /res/** #改变静态资源前缀路径,这个会导致welcome page功能失效
# #static-path-pattern: /** 默认
# web:
# resources:
# static-locations: [classpath:/haha/] #改变静态资源默认文件夹位置
在/resouces/static目录下放入favicon.ico图片文件
2.6、静态资源配置原理
SpringBoot启动默认加载xxxAutoConfiguration类(自动配置)
- 所有的自动配置在org.Springframework.boot:spring-boot-autoconfigure下的文件中
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 {}
给容器中配了什么?
@SuppressWarnings("deprecation")
@Configuration(proxyBeanMethods = false)
@Import(EnableWebMvcConfiguration.class)
@EnableConfigurationProperties({ WebMvcProperties.class,
org.springframework.boot.autoconfigure.web.ResourceProperties.class, WebProperties.class })
@Order(0)
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {}
配置文件的相关属性和xxx进行了绑定,WebMvcProperties==spring.mvc、ResourceProperties==spring.resources
一个配置类中只有一个有参构造
//有参构造器所有参数的值都会从容器中确定
//ResourceProperties resourceProperties;获取和spring.resources绑定所有值的对象
//WebProperties mvcProperties 获取和spring.mvc绑定的所有值的对象
//ListableBeanFactory beanFactory Spring的beanFactory
//HttpMessageConverters 找到所有的HttpMessageConverters
//ResourceHandlerRegistrationCustomizer 找到资源处理器的自定义器 **重点
//DispatcherServletPath
//ServletRegistrationBean 给应用注册Servlet、Filter...
public WebMvcAutoConfigurationAdapter(WebProperties webProperties, WebMvcProperties mvcProperties,
ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider,
ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider,
ObjectProvider<DispatcherServletPath> dispatcherServletPath,
ObjectProvider<ServletRegistrationBean<?>> servletRegistrations) {
this.mvcProperties = mvcProperties;
this.beanFactory = beanFactory;
this.messageConvertersProvider = messageConvertersProvider;
this.resourceHandlerRegistrationCustomizer = resourceHandlerRegistrationCustomizerProvider.getIfAvailable();
this.dispatcherServletPath = dispatcherServletPath;
this.servletRegistrations = servletRegistrations;
this.mvcProperties.checkConfiguration();
}
资源处理默认规则
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
super.addResourceHandlers(registry);
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return;
}
ServletContext servletContext = getServletContext();
addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
registration.addResourceLocations(this.resourceProperties.getStaticLocations());
if (servletContext != null) {
registration.addResourceLocations(new ServletContextResource(servletContext, SERVLET_LOCATION));
}
});
}
spring:
web:
resources:
add-mappings: false #禁用静态资源规则
cache:
period: 11000 #以秒为单位
# mvc:
# static-path-pattern: /res/** #改变静态资源前缀路径
静态资源默认的四个位置
public static class Resources {
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",
"classpath:/resources/", "classpath:/static/", "classpath:/public/" };
/**
* Locations of static resources. Defaults to classpath:[/META-INF/resources/,
* /resources/, /static/, /public/].
*/
private String[] staticLocations = CLASSPATH_RESOURCE_LOCATIONS;
}
欢迎页的默认配置 ```java //说明:HandlerMapping是处理器映射,其中保存了每一个Handler能处理哪些请求。 @Bean public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext, FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(
new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(),
this.mvcProperties.getStaticPathPattern());
welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));
welcomePageHandlerMapping.setCorsConfigurations(getCorsConfigurations());
return welcomePageHandlerMapping;
}
//这里已经将欢迎页写死(”/“.equals),所以我们在配置文件中修改没有用 WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders, ApplicationContext applicationContext, Resource welcomePage, String staticPathPattern) { if (welcomePage != null && “/“.equals(staticPathPattern)) { //要使用欢迎页功能,必须是/** logger.info(“Adding welcome page: “ + welcomePage); setRootViewName(“forward:index.html”); } else if (welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) { //调用Controller /index logger.info(“Adding welcome page template: index”); setRootViewName(“index”); } } ```