28.SpringBoot学习笔记

WebJars与静态资源映射规则

Posted by Chen Xingxu on June 20, 2020

28.SpringBoot学习笔记–WebJars与静态资源映射规则

Spring Boot 对静态资源的映射规则

1、所有 /webjars/** ,都去 classpath:/META-INF/resources/webjars/ 找资源。

WebJars:以 jar 包的方式引入静态资源。

参考 org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration 中的 addResourceHandlers() 方法。

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    if (!this.resourceProperties.isAddMappings()) {
        logger.debug("Default resource handling disabled");
        return;
    }
    Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
    CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
    if (!registry.hasMappingForPattern("/webjars/**")) {
        customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/")
                .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
    }
    String staticPathPattern = this.mvcProperties.getStaticPathPattern();
    if (!registry.hasMappingForPattern(staticPathPattern)) {
        customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)
                .addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
                .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
    }
}

示例

引入 jQuery

进入

https://www.webjars.org/

获取 jQuery 的 WebJar

<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>jquery</artifactId>
    <version>3.5.1</version>
</dependency>

jQuery 的 WebJar 部分结构如下图:

可以得知,访问 jquery.js 的网络路径为

http://localhost:8080/webjars/jquery/3.5.1/jquery.js

2、”/**” 访问当前项目的任何资源,都去静态资源的文件夹找映射

静态资源文件夹如下:

  • classpath:/META-INF/resources/
  • classpath:/resources/
  • classpath:/static/
  • classpath:/public/
  • / : 当前项目的根路径

例如要访问 src\main\resources\static\asserts\js\jquery-3.2.1.slim.min.js,对应的网络路径为

http://localhost:8080/asserts/js/jquery-3.2.1.slim.min.js

org.springframework.boot.autoconfigure.web.ResourceProperties 可以设置和静态资源有关的参数以及缓存时间等。

可以参考 ResourceProperties 类中的 CLASSPATH_RESOURCE_LOCATIONS

private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",
			"classpath:/resources/", "classpath:/static/", "classpath:/public/" };

3、欢迎页; 静态资源文件夹下的所有 index.html 页面被 “/**” 映射

例如要访问 src\main\resources\public\index.html,对应的网络路径为

http://localhost:8080/

参考 org.springframework.boot.autoconfigure.web.servlet.WelcomePageHandlerMapping 中的 welcomePageHandlerMapping() 方法

@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;
}

参考 org.springframework.boot.autoconfigure.web.servlet.WelcomePageHandlerMapping 中的 getWelcomePage() 方法

private Optional<Resource> getWelcomePage() {
    String[] locations = getResourceLocations(this.resourceProperties.getStaticLocations());
    return Arrays.stream(locations).map(this::getIndexHtml).filter(this::isReadable).findFirst();
}

参考 org.springframework.boot.autoconfigure.web.servlet.WelcomePageHandlerMapping 中的 getIndexHtml() 方法

private Resource getIndexHtml(String location) {
    return this.resourceLoader.getResource(location + "index.html");
}

参考 org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties 中的 getStaticPathPattern() 方法

private String staticPathPattern = "/**";

public String getStaticPathPattern() {
    return this.staticPathPattern;
}

4、关于 Favicon

在早期版本中,Spring Boot 对 Favicon 进行了默认支持,但在 Spring Boot 项目的 issues 中有人提出,如果提供默认的 Favicon 可能会导致网站信息泄露。如果用户不进行自定义的 Favicon 的设置,而 Spring Boot 项目会提供默认的图标,那么势必会泄露网站的开发框架。

因此,在 Spring Boot 2.2.x 之后的版本,将默认的 favicon.ico 移除,同时也不再提供上述application.properties 中的属性配置。

5、自定义静态资源文件夹路径

在 application.properties 中配置:

spring.resources.static-locations=classpath:/path01/,classpath:/path02/

注意:配置了 spring.resources.static-locations 后,原来默认的静态资源文件夹路径都会失效。