1、静态资源访问

1.1、静态资源目录

当前项目类路径下:called /static(or /public or /resourcesor /META-INF/resources
访问:当前项目根路径/+静态资源名
原理:静态映射/**
请求进来先去找Controller看能不能处理,不能处理的请求则会交给静态资源处理器,静态资源能找到则访问,如果找不到则为404

2、静态资源访问前缀

默认无前缀,如果要自定义的话在application.yml中做以下操作:

  1. spring:
  2. mvc:
  3. static-path-pattern: /res/**
  4. #static-path-pattern: /** 默认

访问则会成为:当前项目+static-path-pattern+静态资源名=静态资源文件夹下找2.3、webjar

2.3、webjar

自动映射: https://www.webjars.org/

  1. <dependency>
  2. <groupId>org.webjars</groupId>
  3. <artifactId>jquery</artifactId>
  4. <version>3.5.1</version>
  5. </dependency>

引入pom链接,默认访问路径/webjars/**,下面是一个访问的例子:
访问地址: http://localhost:8080/webjars/jquery/3.5.1/jquery.js webjars/后面的地址要按照依赖中的包路径来

2.4、欢迎页支持的几种方式

  • 静态资源路径下 index.html

    • 可以配置静态资源路径
    • 但是不能配置静态资源访问前缀,否则将导致index.html不能被默认访问
      1. spring:
      2. #mvc:
      3. #static-path-pattern: /res/** #改变静态资源前缀路径
      4. #static-path-pattern: /** 默认
      5. web:
      6. resources:
      7. static-locations: [classpath:/haha/] #改变静态资源默认文件夹位置
  • controller能处理/index

    2.5、自定义Favicon网页标签图标

    1. #spring:
    2. # mvc:
    3. # static-path-pattern: /res/** #改变静态资源前缀路径,这个会导致welcome page功能失效
    4. # #static-path-pattern: /** 默认
    5. # web:
    6. # resources:
    7. # static-locations: [classpath:/haha/] #改变静态资源默认文件夹位置

    在/resouces/static目录下放入favicon.ico图片文件
    image.png

    2.6、静态资源配置原理

  • SpringBoot启动默认加载xxxAutoConfiguration类(自动配置)

  • 所有的自动配置在org.Springframework.boot:spring-boot-autoconfigure下的文件中

image.png

  • SpringMvc功能的自动配置类WebMvcAutoConfiguration,生效

    1. @Configuration(proxyBeanMethods = false)
    2. @ConditionalOnWebApplication(type = Type.SERVLET)
    3. @ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
    4. @ConditionalOnMissingBean(WebMvcConfigurationSupport.class) //如果容器中有指定类型的组件则下面的所有的配置都不生效
    5. @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
    6. @AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
    7. ValidationAutoConfiguration.class })
    8. public class WebMvcAutoConfiguration {}
  • 给容器中配了什么?

    1. @SuppressWarnings("deprecation")
    2. @Configuration(proxyBeanMethods = false)
    3. @Import(EnableWebMvcConfiguration.class)
    4. @EnableConfigurationProperties({ WebMvcProperties.class,
    5. org.springframework.boot.autoconfigure.web.ResourceProperties.class, WebProperties.class })
    6. @Order(0)
    7. public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {}
  • 配置文件的相关属性和xxx进行了绑定,WebMvcProperties==spring.mvc、ResourceProperties==spring.resources

  • 一个配置类中只有一个有参构造

    1. //有参构造器所有参数的值都会从容器中确定
    2. //ResourceProperties resourceProperties;获取和spring.resources绑定所有值的对象
    3. //WebProperties mvcProperties 获取和spring.mvc绑定的所有值的对象
    4. //ListableBeanFactory beanFactory Spring的beanFactory
    5. //HttpMessageConverters 找到所有的HttpMessageConverters
    6. //ResourceHandlerRegistrationCustomizer 找到资源处理器的自定义器 **重点
    7. //DispatcherServletPath
    8. //ServletRegistrationBean 给应用注册Servlet、Filter...
    9. public WebMvcAutoConfigurationAdapter(WebProperties webProperties, WebMvcProperties mvcProperties,
    10. ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider,
    11. ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider,
    12. ObjectProvider<DispatcherServletPath> dispatcherServletPath,
    13. ObjectProvider<ServletRegistrationBean<?>> servletRegistrations) {
    14. this.mvcProperties = mvcProperties;
    15. this.beanFactory = beanFactory;
    16. this.messageConvertersProvider = messageConvertersProvider;
    17. this.resourceHandlerRegistrationCustomizer = resourceHandlerRegistrationCustomizerProvider.getIfAvailable();
    18. this.dispatcherServletPath = dispatcherServletPath;
    19. this.servletRegistrations = servletRegistrations;
    20. this.mvcProperties.checkConfiguration();
    21. }

    资源处理默认规则

    1. @Override
    2. protected void addResourceHandlers(ResourceHandlerRegistry registry) {
    3. super.addResourceHandlers(registry);
    4. if (!this.resourceProperties.isAddMappings()) {
    5. logger.debug("Default resource handling disabled");
    6. return;
    7. }
    8. ServletContext servletContext = getServletContext();
    9. addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
    10. addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
    11. registration.addResourceLocations(this.resourceProperties.getStaticLocations());
    12. if (servletContext != null) {
    13. registration.addResourceLocations(new ServletContextResource(servletContext, SERVLET_LOCATION));
    14. }
    15. });
    16. }
    1. spring:
    2. web:
    3. resources:
    4. add-mappings: false #禁用静态资源规则
    5. cache:
    6. period: 11000 #以秒为单位
    7. # mvc:
    8. # static-path-pattern: /res/** #改变静态资源前缀路径

    静态资源默认的四个位置

    1. public static class Resources {
    2. private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",
    3. "classpath:/resources/", "classpath:/static/", "classpath:/public/" };
    4. /**
    5. * Locations of static resources. Defaults to classpath:[/META-INF/resources/,
    6. * /resources/, /static/, /public/].
    7. */
    8. private String[] staticLocations = CLASSPATH_RESOURCE_LOCATIONS;
    9. }

    欢迎页的默认配置 ```java //说明:HandlerMapping是处理器映射,其中保存了每一个Handler能处理哪些请求。 @Bean public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext, FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {

    1. WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(
    2. new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(),
    3. this.mvcProperties.getStaticPathPattern());
    4. welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));
    5. welcomePageHandlerMapping.setCorsConfigurations(getCorsConfigurations());
    6. 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”); } } ```