12.静态资源访问

静态资源:例如js,css,图片等,放在类路径下的:/static (or /public or /resources or /META-INF/resources),可以直接访问
例如:http://localhost:8080/aa.jpg
例如:在resource文件下创建下面存放静态资源的文件夹,将静态资源放入其中可以直接访问

静态资源映射的是/**拦截所有请求,当请求过来时,如:http://localhost:8080/aa.jpg,
    1.会先去动态请求里(Controller)找有没有能处理的
    2.不能处理再去静态资源中(/static (or /public or /resources or /META-INF/resources))找有没有相关资源
    3.都没有返回404
    
例子:

静态资源的访问前缀:

默认情况下,资源映射到/**,但是您可以使用spring.mvc.static-path-pattern属性对其进行调整。
例如,将所有资源重新定位到以下位置/resources/**可以实现:
spring.mvc.static-path-pattern=/resources/**
原因是:在配置拦截器时一般配置的是/**,这样会将静态资源也拦截住,所以可以使用该属性设置静态资源前缀,后续在设置拦截器时可以设置过滤静态资源的路径/**进行拦截


1.静态资源默认是没有前缀的,http://localhost:8080/aa.jpg可以直接访问到,
    设置前缀:
        spring:
              mvc:
                static-path-pattern: /res/**
    这时:只能通过http://localhost:8080/res/aa.jpg才能访问到,
    该标签只是在静态资源访问前加了个前缀,并不需要新建个res的文件夹,静态资源还是在原始的文件夹中存放

2.重新定义静态资源的路径(原始是在:1./static 2./public 3./resources 4./META-INF/resources)
    spring.web.resources.static-locations
    用法:
        spring:
          mvc:
            static-path-pattern: /res/**
          resources:
            static-locations: [classpath:/haha/]
    这时http://localhost:8080/res/aa.jpg,会去haha文件夹找该资源

欢迎页(和静态资源前缀有冲突,bug)
springboot支持欢迎页,在静态资源文件夹里放置index.html(必须是这个),如果找不到,他会寻找一个index模板。如果找到任何一个,它将自动用作应用程序的欢迎页面
即当输入:http://localhost:8080/可以定位到欢迎页

1.在springboot的配置文件中:
    spring:
      #配置了静态资源的前缀,这会影响springboot项目的所有静态资源访问,index.html也是,这时会出现bug:当访问http://localhost:8080/是无法访问到index页面的
      mvc:
        static-path-pattern: /res/**
      resources:
        static-locations: [classpath:/haha/]

但是如果此时把前缀注释掉:
    spring:
        #  mvc:
        #    static-path-pattern: /res/**
          resources:
            static-locations: [classpath:/haha/]
输入:http://localhost:8080/是可以定位到欢迎页的

    结论:当配置了静态资源的前缀时,欢迎页无法正常访问(http://localhost:8080/),但是(http://localhost:8080/res/index.html)可以访问到
静态资源的加载原理
在spring-boot-autoconfigure的jar包中:WebMvcAutoConfiguration里设置了静态资源的加载代码:
    ...
    @ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
    ...
    public class WebMvcAutoConfiguration {
        //1.内部类中开启webmvc的自动配置
        @EnableConfigurationProperties({WebProperties.class})
        public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {
            ...
            protected void addResourceHandlers(ResourceHandlerRegistry registry) {
                super.addResourceHandlers(registry);
                //判断配置文件中的isAddMappings配置是否为false:
                //   1.isAddMappings=false:等于关闭springboot的静态资源访问,所有静态资源不会加载到容器中,无法访问
                //   2.isAddMappings=true:默认是true,开启springboot的静态资源访问   
                //例如:
                //    spring:
                //          resources:
                //               add-mappings: false
                if (!this.resourceProperties.isAddMappings()) {
                    logger.debug("Default resource handling disabled");
                } else {
                    ServletContext servletContext = this.getServletContext();
                    //1.将webjars中的文件加载进容器:webjars是将js文件,jquery,css文件打成jar包
                    this.addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
                    //2.将自定义的静态资源加入容器:getStaticPathPattern是获取配置文件中静态资源配置的前缀
                    this.addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
                        registration.addResourceLocations(this.resourceProperties.getStaticLocations());
                        if (servletContext != null) {
                            registration.addResourceLocations(new Resource[]{new ServletContextResource(servletContext, "/")});
                        }
                    });
                }
            }
            ...
        }
    }
欢迎页的设置和加载
@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext, FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
    WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, this.getWelcomePage(), this.mvcProperties.getStaticPathPattern());
    ...
}
在上述实例化方法里:
    WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders, ApplicationContext applicationContext, Resource welcomePage, String staticPathPattern) {
        //发现这里的前缀是写死的:/**,index.html存在并且静态资源前缀是:/**(默认),则返回欢迎页:index.html,如果设置了静态资源前缀(配置文件中配置),这个条件不满足,所以会出冲突
        if (welcomePage != null && "/**".equals(staticPathPattern)) {
            logger.info("Adding welcome page: " + welcomePage);
            this.setRootViewName("forward:index.html");
        } else if (this.welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) {
            logger.info("Adding welcome page template: index");
            this.setRootViewName("index");
        }
    }
浏览器地址栏图标的选择(springboot2.2版本之前可以这么做)
将需要展示的图标,放入到静态资源文件夹里,名称改为:favicon.ico

posted @ 2022-05-11 21:43  努力的达子  阅读(469)  评论(0编辑  收藏  举报