【SpringBoot】静态资源规则配置

我的springboot版本为

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.5.RELEASE</version>
    </parent>

一.XML配置方式

1.1. /**和/*区别

  • ? 匹配任何单字符
  • * 匹配0个或者任意数量的字符
  • ** 匹配0个或者更多的目录

1.2.spring.mvc.static-path-pattern

spring.mvc.static-path-pattern代表的含义是我们应该以什么样的路径来访问静态资源,默认配置为 /*,换句话说,只有静态资源满足什么样的匹配条件,Spring Boot才会处理静态资源请求,以官方配置为例:

#这表示只有静态资源的访问路径为/statics/**时,才会当作静态资源处理请求
spring.mvc.static-path-pattern=/resources/**,
  • 假设使用默认的端口,那么只有请求地址类似于http://localhost:8080/resources/jquery.js时,SpringBoot才会处理此请求,处理方式是将根据模式匹配后的文件名查找本地文件

那么应该在什么地方查找本地文件呢?

  • 那就需要靠spring.resources.static-locations了。

1.3.spring.resources.static-locations

spring.resources.static-locations 用于告诉Spring Boot在去哪里找静态资源文件,可以配置多个,以逗号分割,根据配置的先后顺序依次进行查找文件

默认的官方配置如下

spring.resources.static-locations=classpath:/static,classpath:/public,classpath:/resources,classpath:/META-INF/resources
  • 继续以上面的请求地址为例,http://localhost:8080/resources/jquery.js就会在上面的四个路径中依次查找是否存在“jquery.js”文件,如果找到了,则返回此文件,否则返回404错误。

如何访问Windows本地路径

# 反斜线,windows目录分隔符,前一个\是转义字符,后一个\是目录分隔符。
spring.resources.static-locations=file:\\D:\\dist\\
# 或spring.resources.static-locations=file:///D:/dist/

等同Spring的XML配置

<mvc:resources mapping="/image/**" location="file:D:/temp/image/">
    <mvc:cache-control max-age="3600" cache-public="true"/>
</mvc:resources>

二.代码配置方式

我们也可以通过@Configuration配置类的方式,实现WebMvcConfigurer接口重写addResourceHandlers方法 来自定义静态资源映射目录,但会覆盖默认的静态资源配置

Spring5弃用了WebMvcConfigurerAdapter类,改为使用WebMvcConfigurer接口

  • addResourceHandler: 指定映射对外暴露的访问路径
  • addResourceLocations: 指定文件放置的目录

springboot 1.x配置-继承WebMvcConfigurerAdapter类

@Configuration
public class MyWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter {
    
    
 
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
    
            
    	/**
         * 资源映射路径
         * addResourceHandler:访问映射路径
         * addResourceLocations:资源绝对路径
         */
        registry.addResourceHandler("/image/**")
        		.addResourceLocations("file:D:/temp/image/")
          		.setCacheControl(CacheControl.maxAge(1, TimeUnit.HOURS).cachePublic());
    }
}

springboot 2.x配置-实现WebMvcConfigurer接口

@Configuration
public class MyWebAppConfigurer implements WebMvcConfigurer {
    
    
    /**
      * 资源映射路径
      * addResourceHandler:访问映射路径
      * addResourceLocations:资源绝对路径
      */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
    
      
        registry.addResourceHandler("/image/**")
        		.addResourceLocations("file:D:/temp/image/")
          		.setCacheControl(CacheControl.maxAge(1, TimeUnit.HOURS).cachePublic());
    }
}

等同Spring的XML配置

<mvc:resources mapping="/image/**" location="file:D:/temp/image/">
    <mvc:cache-control max-age="3600" cache-public="true"/>
</mvc:resources>

如何访问classPath下面的文件

 registry.addResourceHandler("/image/**").addResourceLocations("classpath:/temp-rainy/");

三.WebJars方式

  • WebJars就是将前端资源(css,js,image,html等等)打包到jar中,然后使用基于JVM的包管理器(比如 Maven、Gradle 等)管理前端依赖。

  • 官网地址 : https://www.webjars.org/

打开网站可以看到下面有很多前端js组件的maven引入
在这里插入图片描述

  • SpringBoot中也可以通过WebJars来访问静态资源。默认/webjars/**映射到 classpath:/META-INF/resources/webjars/

    **/webjars/****:表示/webjars/目录下的所有文件,及存在其目录下的jar包中的所有文件。

    • 默认情况下我们需要访问WebJars中的资源,需要将其jar包放到classpath:/META-INF/resources/webjars/目录中。

SpringBoot对WebJar的支持
查看WebMWebMVCAutoConfiguration源码如下:
在这里插入图片描述
其中绿色方框代码说明SpringBoot如何对WebJars进行支持:所有 /webjars/**的请求都去 classpath:/META-INF/resources/webjars/ 找资源

页面使用

  • pom.xml中引入jquery的WebJars,默认会被放在classpath:/META-INF/resources/webjars/目录中
 <dependency>
      <groupId>org.webjars</groupId>
      <artifactId>jquery</artifactId>
      <version>2.1.1</version>
  </dependency>
  • 在前端webjars.html页面中引入jquery
<script src="/webjars/jquery/2.1.1/jquery.js"></script>
  • 访问指定页面
    在这里插入图片描述

WebJar版本号统一管理

pom.xml添加依赖如下

        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>webjars-locator</artifactId>
            <version>0.40</version>
        </dependency>

此时,使用(带版本号和不带版本号)的请求都可以正确获取资源!
在这里插入图片描述
注释webjars-locator依赖发现又不可以了在这里插入图片描述

四.SpringBoot静态资源映射规则

在SpringBoot中静态资源和WebJar的相关配置在WebMvcAutoConfiguration类中。

  • 通过源码分析:所有/webjars/**的请求都去classpath:/META-INF/resources/webjars/找资源。
    在这里插入图片描述

通过源码分析: SpringBoot是在ResourceProperties类中设置和静态资源有关的参数,比如缓存时间设置。

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

在这里插入图片描述
访问/**访问当前项目的任何资源都会首先去这些静态资源目录查找:

classpath:/META-INF/resources/,
classpath:/resources/,
classpath:/static/, 
classpath:/public/

通过源码分析欢迎页index.html是通过查找所有静态资源目录下的index.html页面,按照目录优先级返回

在这里插入图片描述

五.Spring如何访问如Webapp下的静态资源

我们之前创建的JavaWeb工程的时候,直接把静态资源,比如html文件、图片等放在src/main/webapp目录下,在浏览器中是直接可以访问到这些静态资源的。那么对于springboot来说该如何处理这些资源文件呢?

springboot对静态资源的默认扫描路径是:

classpath:/META-INF/resources
classpath:/resources
classpath:/public
classpath:/static

springBoot默认是没有webapp目录的,需要自己创建,放在和java,resource统一目录下,如下:
在这里插入图片描述

主要是配置两个路径
在这里插入图片描述

pom.xml配置打包路径,将对应资源编译到target目录

        <resources>
            <!--打包webapp目录下的所有内容到classpath:META-INF/resources-->
            <resource>
                <directory>src/main/webapp</directory>
                <targetPath>META-INF/resources</targetPath>
                <includes>
                    <include>**/**</include>
                </includes>
            </resource>
            <!--打包resources目录下的所有内容到classpath:/-->
            <resource>
                <directory>src/main/resources/</directory>
                <includes>
                    <include>**/**</include>
                </includes>
            </resource>
        </resources>

编译后的目录结构
在这里插入图片描述

请求 :http://localhost:8080/img2/4.jpg
在这里插入图片描述
请求 :http://localhost:8080/img2/5.jpg
在这里插入图片描述
请求 :http://localhost:8080/img2/6.jpg
在这里插入图片描述

在这里插入图片描述


从源码可以看出静态资源文件夹默认配置
在这里插入图片描述

spring.resources.static-locations
用于告诉Spring Boot应该在何处查找静态资源文件,这是一个列表性的配置,查找文件时会依赖于配置的先后顺序依次进行。类似于springmvc中的location标签,默认的官方配置如下:

  • spring.resources.static-locations=
    classpath:/META-INF/resources
    classpath:/resources,
    classpath:/public,
    classpath:/static,

六.SpringBoot整合shiro静态资源文件被拦截解决方法

目录结构
在这里插入图片描述

6.1.默认spring.mvc.static-path-pattern配置

不在springBoot配置中spring.mvc.static-path-pattern.即静态资源匹配条件,默认配置为 /*, 任意静态资源请求都会去以下目录查找

classpath:/META-INF/resources
classpath:/resources
classpath:/public
classpath:/static
  1. shirFilter新增配置-访问静态资源/css,/js,/image请求路径放行
@Bean
    public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
    
    
        System.out.println("ShiroConfiguration.shirFilter()");
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

        // 必须设置 SecurityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
        shiroFilterFactoryBean.setLoginUrl("/login");
        // 登录成功后要跳转的链接
        shiroFilterFactoryBean.setSuccessUrl("/index");
        //未授权界面;
        shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");

        //拦截器.
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
        //自定义拦截器
        Map<String, Filter> customisedFilter = new HashMap<>();
        customisedFilter.put("url", getUrlPathMatchingFilter());
        //配置映射关系
        filterChainDefinitionMap.put("/login", "anon");
        filterChainDefinitionMap.put("/index", "anon");
        //springboot默认把所有的静态资源都映射到static目录了
        //也就是说本来的http://localhost:8888/static/css/main.css 需要改成
        //http://localhost:8888/css/main.css才可以访问
        filterChainDefinitionMap.put("/image/**", "anon");//img
        filterChainDefinitionMap.put("/css/**", "anon");//css
        filterChainDefinitionMap.put("/js/**", "anon");//js
        filterChainDefinitionMap.put("/config/**", "anon");
        filterChainDefinitionMap.put("/404", "anon");
        filterChainDefinitionMap.put("/500", "anon");
        filterChainDefinitionMap.put("/doLogout", "logout");
        filterChainDefinitionMap.put("/**", "url");
        shiroFilterFactoryBean.setFilters(customisedFilter);
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

        return shiroFilterFactoryBean;
    }
  1. 浏览器直接请求是可以访问的
    在这里插入图片描述

  2. jsp中指定的href=/css/style.css
    在这里插入图片描述

6.2.配置了spring.mvc.static-path-pattern

  1. 全局配置文件application.properties新增配置
# 这表示只有静态资源的访问路径为/statics/**时,才会当作静态资源处理请求
spring.mvc.static-path-pattern=/statics/**
  1. shirFilter新增配置-对/statics请求路径放行
    @Bean
    public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
    
    
        System.out.println("ShiroConfiguration.shirFilter()");
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

        // 必须设置 SecurityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
        shiroFilterFactoryBean.setLoginUrl("/login");
        // 登录成功后要跳转的链接
        shiroFilterFactoryBean.setSuccessUrl("/index");
        //未授权界面;
        shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");

        //拦截器.
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
        //自定义拦截器
        Map<String, Filter> customisedFilter = new HashMap<>();
        customisedFilter.put("url", getUrlPathMatchingFilter());
        //配置映射关系
        filterChainDefinitionMap.put("/login", "anon");
        filterChainDefinitionMap.put("/index", "anon");
        //#核心配置文件配置=>静态资源位置 spring.mvc.static-path-pattern=/statics/**
        //访问时 http://localhost:8080/statics/css/style.css
        filterChainDefinitionMap.put("/statics/**", "anon");
        filterChainDefinitionMap.put("/config/**", "anon");
        filterChainDefinitionMap.put("/404", "anon");
        filterChainDefinitionMap.put("/500", "anon");
        filterChainDefinitionMap.put("/doLogout", "logout");
        filterChainDefinitionMap.put("/**", "url");
        shiroFilterFactoryBean.setFilters(customisedFilter);
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

        return shiroFilterFactoryBean;
    }
  1. 浏览器请求在这里插入图片描述
  2. jsp中指定的href=/statics/css/style.css在这里插入图片描述

Spring Boot 静态资源访问原理解析

猜你喜欢

转载自blog.csdn.net/qq877728715/article/details/110422199
今日推荐