Spring Boot 静态资源访问

1、静态资源访问

1.1 静态资源目录

  • 只要静态资源放在类路径下: /static/public/resources/META-INF/resources这几个文件夹下,都可以通过当前项目根路径/ + 静态资源名 直接访问到。
  • 比如,下面public文件夹的资源,可以直接通过http://localhost:8080/curley3.jpg的URI直接访问到。
    在这里插入图片描述
  • 原理:使用了静态映射/**,也就是所有包含了所有请求。请求进来,先去找Controller看能不能处理。不能处理的所有请求又都交给静态资源处理器,静态资源处理器在所有静态资源中找有没有需要的资源,如果有则返回,静态资源也找不到则响应404页面。
  • 其中,有两个重要的默认参数
    spring:
      mvc:
        static-path-pattern: /**
    
      resources:
        static-locations: [classpath:/META-INF/resources/, classpath:/resources/, classpath:/static/, classpath:/public/]
    

    static-path-pattern 表示静态路径映射,static-locations 表示静态资源地址。

  • 通过在配置文件中修改上述两个参数,可以实现只针对指定的映射,用静态资源处理器处理。并且可以指定静态资源所保存的路径。

1.2 webjar

  • 之前的静态资源,比如jQuery,需要手动下载放在resources内,而如今可以通过maven的方式添加,自动映射为/webjars/**
    <dependency>
    	<groupId>org.webjars</groupId>
    	<artifactId>jquery</artifactId>
    	<version>3.5.1</version>
    </dependency>
    
  • 访问地址为http://localhost:8080/webjars/jquery/3.5.1/jquery.js,后面地址要按照依赖里面的包路径。
  • 在使用jQuery的时候,就可以这样写。
    <script type="text/javascript" src="http://localhost:8080/webjars/jquery/3.5.1/jquery.js"></script>
    
  • 更多资源,可以在https://www.webjars.org/ 上找到。

欢迎页访问

  • 之前提到的任意一个静态资源目录下放index.html 文件,都可以直接作为欢迎页被访问。
  • 比如,上图已经放了一个index.html 文件,直接访问地址http://localhost:8080/ ,就可以访问到主页。

自定义Favicon

  • 浏览器上面会有一个小图标,可以直接下载一个ico文件,命名为favicon.ico 放在静态资源目录下,也会被自动加载。
    在这里插入图片描述

静态资源配置原理

  • Spring MVC 在Spring Boot中有一个默认的自动配置类,当我们没有定制一个配置类的时候,默认使用官方的。
    @ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
    @ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
    @AutoConfigureOrder(-2147483638)
    @AutoConfigureAfter({DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class})
    public class WebMvcAutoConfiguration {
    
  • 里面包含了大部分Spring MVC所需要的组件,在加载的时候,就会将组件放入IOC容器中。
  • WebMvcAutoConfiguration 内部,有一个配置类 WebMvcAutoConfigurationAdapter 自动加载配置的内容。
    @Configuration(
        proxyBeanMethods = false
      )
      @Import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class})
      @EnableConfigurationProperties({WebMvcProperties.class, ResourceProperties.class, WebProperties.class})
      @Order(0)
      public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {
    

    ResourceProperties 对应 spring.resourcesWebMvcProperties 对应 spring.mvc

  • WebMvcAutoConfiguration 内部,又有一个配置类EnableWebMvcConfiguration 加载一些资源。
    在这里插入图片描述
    @EnableConfigurationProperties({WebProperties.class})
    public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {
    
  • 该类继承一个父类WebMvcConfigurationSupport ,该父类在加载的时候,会调用一个resourceHandlerMapping() 方法,加载一个资源的处理器映射。其中有一个重点方法,this.addResourceHandlers(registry) ,根据静态资源,将静态资源处理器注册。
    @Bean
      @Nullable
      public HandlerMapping resourceHandlerMapping(@Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager, @Qualifier("mvcConversionService") FormattingConversionService conversionService, @Qualifier("mvcResourceUrlProvider") ResourceUrlProvider resourceUrlProvider) {
        Assert.state(this.applicationContext != null, "No ApplicationContext set");
        Assert.state(this.servletContext != null, "No ServletContext set");
        PathMatchConfigurer pathConfig = this.getPathMatchConfigurer();
        ResourceHandlerRegistry registry = new ResourceHandlerRegistry(this.applicationContext, this.servletContext, contentNegotiationManager, pathConfig.getUrlPathHelper());
        this.addResourceHandlers(registry);
        AbstractHandlerMapping handlerMapping = registry.getHandlerMapping();
        if (handlerMapping == null) {
          return null;
        } else {
          if (pathConfig.getPatternParser() != null) {
            handlerMapping.setPatternParser(pathConfig.getPatternParser());
          } else {
            handlerMapping.setUrlPathHelper(pathConfig.getUrlPathHelperOrDefault());
            handlerMapping.setPathMatcher(pathConfig.getPathMatcherOrDefault());
          }
    
          handlerMapping.setInterceptors(this.getInterceptors(conversionService, resourceUrlProvider));
          handlerMapping.setCorsConfigurations(this.getCorsConfigurations());
          return handlerMapping;
        }
      }
    
  • EnableWebMvcConfiguration 中,有该方法重写。静态资源及其映射就此被添加。
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
      super.addResourceHandlers(registry);
      if (!this.resourceProperties.isAddMappings()) {
        logger.debug("Default resource handling disabled");
      } else {
        ServletContext servletContext = this.getServletContext();
        this.addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
        this.addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
          registration.addResourceLocations(this.resourceProperties.getStaticLocations());
          if (servletContext != null) {
            registration.addResourceLocations(new Resource[]{new ServletContextResource(servletContext, "/")});
          }
    
        });
      }
    }
    

欢迎页处理规则

  • EnableWebMvcConfiguration 中,还有一个返回欢迎页的处理器映射的方法。
    @Bean
    public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext, FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
      WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, this.getWelcomePage(), this.mvcProperties.getStaticPathPattern());
      welcomePageHandlerMapping.setInterceptors(this.getInterceptors(mvcConversionService, mvcResourceUrlProvider));
      welcomePageHandlerMapping.setCorsConfigurations(this.getCorsConfigurations());
      return welcomePageHandlerMapping;
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值