SpringBoot⑥Web开发:静态资源、首页和图标

7、Web开发:静态资源

在项目中需要使用到大量的 JS、CSS 等静态资源,如何导入静态资源呢?

7.1、存放位置

  • 以前的 web 项目:放在 webapp 目录(或 web 目录)下;
  • Spring Boot 项目静态资源映射
    1. 通过 webjars
    2. 通过 staticPathPattern

7.2、静态资源映射

Spring Boot 中,静态资源映射规则规定了静态资源的导入方式和存放路径等等;

静态资源映射规则在以下类中体现。

  1. WebMvcAutoConfiguration类

    • 配置类
    • 定义了有关 Spring MVCweb 配置

    SpringBoot⑥Web开发:静态资源、首页和图标

  2. WebMvcAutoConfigurationAdapter类

    • 配置类:这个类是 Spring Boot 内部提供,专门用于处理用户自行添加的配置

    • WebMvcAutoConfiguration 类的内部类

      SpringBoot⑥Web开发:静态资源、首页和图标

7.3、addResourceHandlers()

查看WebMvcAutoConfigurationAdapter类addResourceHandlers()方法

  • 先做一个 if 判断:判断是否启动默认资源处理,未启动则结束方法体;

  • 调用两个 addResourceHandler 重载方法:配置默认静态资源映射路径

    (在 Spring Boot 的早期版本里,这两个重载方法没有被抽取出来,而是写在这个方法的内部,版本更新后将其抽取成方法)

SpringBoot⑥Web开发:静态资源、首页和图标

7.4、默认静态资源映射

isAddMappings()

/**
* Whether to enable default resource handling.
*/
private boolean addMappings = true;

public boolean isAddMappings() {
   return this.addMappings;
}
  1. 返回一个变量:addMappings
  2. 变量含义:是否启动默认资源处理(即默认静态资源映射),默认为 true
    • 如果没有自定义静态资源映射路径:此时启动默认资源处理(变量值 true);
    • 如果自定义静态资源映射路径:此时禁用默认资源处理,而是采用自定义的配置(变量值 false)。

7.5、映射规则

  • 如果采取默认资源处理,则遵守以下前两种规则:WebJarsstaticPathPattern
  • 如果采取自定义,则遵守第三种规则:自定义映射路径。

7.5.1、webjars

  1. 通过 jar 包的方式引入静态资源,映射关系如下
    • 请求路径/webjars/**
    • 资源路径classpath:/META-INF/resources/webjars/
  2. 映射规则:访问请求路径/webjars/**,会映射到相应的资源路径classpath:/META-INF/resources/webjars/,寻找相应的资源
  3. jar 包引入方式
    • 以前的项目:先下载 jar 包,再将其导入项目;
    • Spring Boot 项目:通过 Mavenpom 依赖)来引入 jar 包,相关依赖见 WebJars 网站

举例:引入 jQuery 并访问

  1. 导入依赖

    <dependency>
        <groupId>org.webjars</groupId>
        <artifactId>jquery</artifactId>
        <version>3.6.0</version>
    </dependency>
    
  2. 查看资源路径

    SpringBoot⑥Web开发:静态资源、首页和图标

  3. 通过请求路径访问资源

    SpringBoot⑥Web开发:静态资源、首页和图标

7.5.2、staticPathPattern

  1. 通过 staticPathPattern 变量映射静态资源,映射关系如下:

    • 请求路径this.mvcProperties.getStaticPathPattern()

      • 返回一个变量:staticPathPattern
      • 变量含义:静态资源的路径模式。默认为/**,表示当前项目的任意资源。
      /**
       * Path pattern used for static resources.
       */
      private String staticPathPattern = "/**";
      
      public String getStaticPathPattern() {
          return this.staticPathPattern;
      }
      
    • 资源路径this.resourceProperties.getStaticLocations()

      • 返回一个变量:staticLocations
      • 变量含义:静态资源的位置,默认值为数组CLASSPATH_RESOURCE_LOCATIONS
        • classpath:/META-INF/resources/
        • classpath:/resources/
        • classpath:/static/
        • classpath:/public/
      private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",
      		"classpath:/resources/", "classpath:/static/", "classpath:/public/" };
      
      private String[] staticLocations = CLASSPATH_RESOURCE_LOCATIONS;
      
      public String[] getStaticLocations() {
         return this.staticLocations;
      }
      
  2. 映射规则:访问请求路径/**,会映射到相应的4个资源路径,寻找相应的资源。

    • classpath:/META-INF/resources/
    • classpath:/resources/
    • classpath:/static/
    • classpath:/public/

举例:创建一个文件并访问

  1. static 目录下创建一个文件:target.txt

    SpringBoot⑥Web开发:静态资源、首页和图标

  2. 通过请求路径访问资源:成功访问

    SpringBoot⑥Web开发:静态资源、首页和图标

  3. 探讨资源访问优先级

    • 在类路径下的三个文件夹(resourcesstaticpublic)分别创建一个target.txt

    • 两两测试,探究其优先级;

  • :最外层的 resources 目录代表类路径,即classpath:/(注意与classpath:/resources/区分)

  • 结论类路径下的优先级:resources > static > public(即源码中的顺序优先级递减)

    SpringBoot⑥Web开发:静态资源、首页和图标

7.5.3、自定义映射路径

  • 添加配置:application.properties

    spring.web.resources.static-locations=classpath:/jaywee/
    
  • 注意一旦自定义资源路径,会关闭默认资源处理(即默认静态资源映射),此时禁用所有默认静态资源映射(webjarsstaticPathPattern 的四个映射路径)。

    • 参考7.4,原因是 addMappings 的值为 false,结束了方法体;
    • 因此没有后续的静态资源映射的相关设置,相当于禁用了默认静态资源映射;

7.6、小结

  1. Spring Boot 定义了静态资源映射规则,规定了静态资源的导入方式和存放路径;
  2. 上述规则,在WebMvcAutoConfiguration类的内部类WebMvcAutoConfigurationAdapter类addResourceHandlers()方法中体现;
  3. 如果自定义,则采取自定义映射规则;
  4. 如果没有自定义,则采取默认静态资源映射,包括以下两种映射规则:
    • webjars
      • 请求路径/webjars/**
      • 资源路径classpath:/META-INF/resources/webjars/
    • staticPathPattern
      • 请求路径/**
      • 映射路径:4个,优先级依次递减
        1. classpath:/META-INF/resources/
        2. classpath:/resources/
        3. classpath:/static/
        4. classpath:/public/

8、Web开发:首页和图标

启动 Spring Boot 项目并访问时

  • 没有设置首页:会打开错误页面 Whitelabel Error Page
  • 没有设置图标:页面栏的左上角是浏览器的默认图标;

SpringBoot⑥Web开发:静态资源、首页和图标

8.1、资源映射

类似7、静态资源,设置首页和图标也有相应的规则。

在以下类中体现。

  1. WebMvcAutoConfiguration类

    • 配置类
    • 定义了有关 Spring MVCweb 配置

    SpringBoot⑥Web开发:静态资源、首页和图标

  2. EnableWebMvcConfiguration类

    • 配置类
    • WebMvcAutoConfiguration 类的内部类

    SpringBoot⑥Web开发:静态资源、首页和图标

8.2、welcomePageHandlerMapping()

查看EnableWebMvcConfiguration类welcomePageHandlerMapping()方法

SpringBoot⑥Web开发:静态资源、首页和图标

getWelcomePage()

获取欢迎页

private Resource getWelcomePage() {
   for (String location : this.resourceProperties.getStaticLocations()) {
      Resource indexHtml = getIndexHtml(location);
      if (indexHtml != null) {
         return indexHtml;
      }
   }
   ServletContext servletContext = getServletContext();
   if (servletContext != null) {
      return getIndexHtml(new ServletContextResource(servletContext, SERVLET_LOCATION));
   }
   return null;
}

使用 foreach 循环,把getStaticLocations()中的每个值依次赋给变量 location

  • location-- getStaticLocations() :四个资源路径,具体见7.5.2

  • 调用 getIndexHtml() 方法,判断非空则返回

  • 如果 staticLocations 的四个资源路径下都没有index.html,获取 servletContext 上下文对象

    • 如果上下文对象非空,则调用并返回 getIndexHtml

    • 参数:上下文对象SERVLET_LOCATION

      private static final String SERVLET_LOCATION = "/";
      

getIndexHtml()

根据路径获取首页

  • 重载方法,参数为获取 location 路径下对应的资源;
  • 如果 location 路径下的资源存在index.html,则返回该页面,否则返回 null
private Resource getIndexHtml(String location) {
    return getIndexHtml(this.resourceLoader.getResource(location));
}

private Resource getIndexHtml(Resource location) {
    try {
        Resource resource = location.createRelative("index.html");
        if (resource.exists() && (resource.getURL() != null)) {
            return resource;
        }
    }
    catch (Exception ex) {
    }
    return null;
}

测试

  1. static 目录下创建index.html

    SpringBoot⑥Web开发:静态资源、首页和图标

  2. 启动 Spring Boot 项目,成功访问首页

    SpringBoot⑥Web开发:静态资源、首页和图标

  3. 探讨首页映射优先级

    • 在类路径下的三个文件夹(resourcesstaticpublic)分别创建一个index.html

    • 结论优先级:resources > static > public(即源码中的顺序优先级递减)

8.3、图标

原理是类似的,结论:把图标正确命名:favicon.ico并放在规定的资源映射路径中即可。

8.4、小结

首页和图标也可以当成静态资源,遵守静态资源映射规则。

上一篇:eclipse项目丢失.project .classpath


下一篇:springboot 学习(七) springboot静态资源路径