SpringBoot中静态资源的访问

in 编程
关注公众号【好便宜】( ID:haopianyi222 ),领红包啦~
阿里云,国内最大的云服务商,注册就送数千元优惠券:https://t.cn/AiQe5A0g
腾讯云,良心云,价格优惠: https://t.cn/AieHwwKl
搬瓦工,CN2 GIA 优质线路,搭梯子、海外建站推荐: https://t.cn/AieHwfX9

一、静态资源的映射规则

1.对哪些目录映射?

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

意思是:我们在上面的五个目录下放静态资源文件(比如:jq.js等),可以直接访问(http://localhost:8080/jq.js),类似以前web项目的webapp下,放到其他目录无法被访问。

2.为什是这几个目录呢?

    2.1看源码就知道

SpringBoot自动配置的WebMvcAutoConfirarution.java类:

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

ResourceProperties

@ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)
public class ResourceProperties {

    //我们可以看到静态资源的映射路径
	private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
			"classpath:/META-INF/resources/", "classpath:/resources/",
			"classpath:/static/", "classpath:/public/" };

    ...
}

总的来说:

WebMvcAutoConfiguration类自动为我们注册了如下目录为静态资源目录,也就是说直接可访问到资源的目录。

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

优先级从上到下。

所以,如果static里面有个index.html,public下面也有个index.html,则优先会加载static下面的index.html,因为优先级!

看源码


public class WebMvcAutoConfiguration {
        //...

        @Bean
		public WelcomePageHandlerMapping welcomePageHandlerMapping(
				ApplicationContext applicationContext) {
			return new WelcomePageHandlerMapping(
					new TemplateAvailabilityProviders(applicationContext),
					applicationContext, getWelcomePage(),
					this.mvcProperties.getStaticPathPattern());
		}
        

         private Optional<Resource> getWelcomePage() {
            // 遍历默认静态资源目录后面拼接个index.html的数组
            // 比如:[/static/index.html, /public/index.html等等]
			String[] locations = getResourceLocations(
					this.resourceProperties.getStaticLocations());
			return Arrays.stream(locations).map(this::getIndexHtml)
					.filter(this::isReadable).findFirst();
		}
      
         // 下面这段代码通俗易懂,就是给默认静态资源目录后面拼接个index.html并返回,比如:/static/index.html
          private String[] getStaticWelcomePageLocations() {
              String[] result = new String[this.staticLocations.length];
                  for (int i = 0; i < result.length; i++) {
                      String location = this.staticLocations[i];
                      if (!location.endsWith("/")) {
                          location = location + "/";
             }
                   result[i] = location + "index.html";
         }
      return result;
} 

翻译内容成如下映射规则:

return new WelcomePageHandlerMapping(
    "classpath:/META-INF/resources/index.html",
    "classpath:/resources/index.html",
    "classpath:/static/index.html",
    "classpath:/public/index.html",
    "/index.html"
    , "/**");

也就是 WebMvcAutoConfiguration类自动为我们注册了如下文件为默认首页

classpath:/META-INF/resources/index.html
classpath:/resources/index.html
classpath:/static/index.html 
classpath:/public/index.html
/index.html

优先级从上到下。

所以,如果static里面有个index.html,public下面也有个index.html,则优先会加载static下面的index.html,因为优先级!

如果使用了spring-boot-starter-thymeleaf,并且编写IndexController,那么就会访问templates下的index.html

<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

IndexController

@Controller
public class IndexController {

    @RequestMapping({"", "/"})
    public String index() {
        return "index";
    }
}

默认如果不添加spring-boot-starter-thymeleaf,也不添加IndexController,可以会到static下的index.html,添加了spring-boot-starter-thymeleaf,不编写IndexController,默认会跳到static/index.html,而不是templates/index.html

关注公众号【好便宜】( ID:haopianyi222 ),领红包啦~
阿里云,国内最大的云服务商,注册就送数千元优惠券:https://t.cn/AiQe5A0g
腾讯云,良心云,价格优惠: https://t.cn/AieHwwKl
搬瓦工,CN2 GIA 优质线路,搭梯子、海外建站推荐: https://t.cn/AieHwfX9
扫一扫关注公众号添加购物返利助手,领红包
Comments are closed.

推荐使用阿里云服务器

超多优惠券

服务器最低一折,一年不到100!

朕已阅去看看