我是靠谱客的博主 冷傲超短裙,最近开发中收集的这篇文章主要介绍WebJars与静态资源映射规则(基于SpringBoot最新版本2.5.2,指正了老版本的博客中的问题),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述


文章目录

    • 1️⃣ WebJars
      • 1.1 简介
      • 1.2 通过SpringBoot使用WebJars
    • 2️⃣ 静态资源映射规则
      • 2.1 WebJars访问支持
      • 2.2 项目静态资源访问支持
      • 2.3 首页映射
      • 2.4 自定义静态资源访问路径
      • 2.5 自定义图标(favicon.ico)

环境:

名词版本
JDK1.8
Spring Boot2.5.2




1️⃣ WebJars

1.1 简介

  • WebJars是一个将前端的静态资源都封装成jar包的技术。在没有这项技术的时候,所有的资源都要手动的放在webapp目录下,但是这样手动管理十分容易拷贝错误、拷错文件夹等等情况。而使用WebJars技术可以通过jar的方式访问静态资源文件,减少了可能发生的错误


1.2 通过SpringBoot使用WebJars

  • 首先获取前端框架的依赖,可以通过webjars官网或maven中央仓库查询

  • 然后像正常的后端jar包一样导入依赖即可

    在这里插入图片描述

  • 具体如何使用,见下文


2️⃣ 静态资源映射规则

  • 首先放上SpringBoot对静态资源进行映射的关键代码,并对其映射规则进行解析

  • addResourceHandlers(WebMvcAutoConfiguration)

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
       if (!this.resourceProperties.isAddMappings()) {
          logger.debug("Default resource handling disabled");
          return;
       }
       // 2.1 WebJars访问支持
       addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
       // 2.2 项目静态资源访问支持 
       addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
          registration.addResourceLocations(this.resourceProperties.getStaticLocations());
          if (this.servletContext != null) {
             ServletContextResource resource = new ServletContextResource(this.servletContext, SERVLET_LOCATION);
             registration.addResourceLocations(resource);
          }
       });
    }
    


2.1 WebJars访问支持

  • 通过上方代码标记处可以看到,SpringBoot对webjars的访问定义的规则如下:

    /webjars/下的任意多级子目录下文件,都会映射到类路径下的/META-INF/resources/webjars文件夹下

  • 以JQuery为例,可以看到JQuery的webjar的结构如下

    在这里插入图片描述

  • 通过映射规则可知,若要访问jquery.min.js,则访问路径是:

    http://localhost:8080/webjars/jquery/1.12.4/jquery.min.js

    在这里插入图片描述


2.2 项目静态资源访问支持

  • SpringBoot一共定义了5个规则对项目的静态资源进行访问

    1. classpath:/META-INF/resources/

      类路径下的META-INF文件夹下的resources文件夹

    2. classpath:/resources/

      类路径下的resources文件夹

    3. classpath:/static/

      类路径下的static文件夹

    4. classpath:/public/

      类路径下的public文件夹

    5. /

      项目的根路径。需要注意的是这个映射规则截止SpringBoot 2.5.2,仍处于失效状态,详见下文

    定义的地方见WebProperties的内部类Resources的CLASSPATH_RESOURCE_LOCATIONS字符串常量数组

    在这里插入图片描述

  • 以classpath:/static/为例进行演示:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jMOqm3B5-1626702970252)(images/image-20210719193706694.png)]
    在这里插入图片描述

  • 虽然有5条静态映射规则,但是截止SpringBoot 2.5.2版本,经过测试只有前4个是能成功进行映射的。第5条/,即项目的根目录并不能进行映射,该问题已经有人发到了SpringBoot的issues中,见issues#27051

  • 笔者在发现这个问题后曾翻阅无数博客,许多人都是直接照搬尚硅谷的笔记而不经过相关测试,全然没有提及这个问题,因此在这特意指出


2.3 首页映射

  • SpringBoot会自动检测静态资源目录(上文提到的5个路径)下是否有index.html,若有的话会将其作为项目的欢迎页,效果等同于在web.xml中设置的welcome-file

  • 寻找静态资源目录下的index.html作为首页的关键代码如下:

    welcomePageHandlerMapping(WebMvcAutoConfiguration)

    @Bean
    public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,
          FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
        // 关键: getWelcomePage方法
       WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(
             new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(),
             this.mvcProperties.getStaticPathPattern());
       welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));
       welcomePageHandlerMapping.setCorsConfigurations(getCorsConfigurations());
       return welcomePageHandlerMapping;
    }
    
  • 通过下面的代码可以看到,的确是查找静态资源目录下的index.html

    public class WebProperties {
        // ...
        
        public static class Resources {
    
            private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {"classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/" };
    
            public String[] getStaticLocations() {
                return this.staticLocations;
            }
        }
    }
    
    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;
    }
    
    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;
    }
    


2.4 自定义静态资源访问路径

  • 除了使用默认的5个静态资源访问路径,SpringBoot也允许自定义静态资源访问路径。通过在application.properties中设置spring.web.resources.static-locations属性即可。多个静态资源访问路径通过逗号分隔

  • 例子如下:

    spring.web.resources.static-locations=classpath:/mystatic/,classpath:/mypublic
    
  • 需要注意的是:自定义的静态资源访问路径会覆盖默认的静态资源访问路径


2.5 自定义图标(favicon.ico)

  • SpringBoot 2.2以前,只要在静态资源路径下放一个favicon.ico,就可以全局设置当前项目的所有界面的顶部logo,但是相关的代码已经在SpringBoot 2.2版本移除

  • 然而,许多看尚硅谷SpringBoot视屏的人仍在锲而不舍的在博客中提到此功能,着实让人无语
    在这里插入图片描述

最后

以上就是冷傲超短裙为你收集整理的WebJars与静态资源映射规则(基于SpringBoot最新版本2.5.2,指正了老版本的博客中的问题)的全部内容,希望文章能够帮你解决WebJars与静态资源映射规则(基于SpringBoot最新版本2.5.2,指正了老版本的博客中的问题)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(50)

评论列表共有 0 条评论

立即
投稿
返回
顶部