004.SpringBoot web篇:静态资源管理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sld880311/article/details/79460337

默认静态资源管理

在web开发中,静态资源的访问是必不可少的,如:图片、js、css 等资源的访问。spring Boot 对静态资源访问提供了很好的支持,基本使用默认配置就能满足开发需求。

SpringBoot默认为我们提供了静态资源处理,使用WebMvcAutoConfiguration 中的配置各种属性。(注意:如果想自己完全控制webmvc 则可以在自己定义的@Configuration配置类中增加@EnableWebMvc,使默认的WebMvcAutoConfiguration失效)查看WebMvcAutoConfiguration源码:

    // Defined as a nested config to ensure WebMvcConfigurer is not read when not
    // on the classpath
    @Configuration
    @Import(EnableWebMvcConfiguration.class)
    @EnableConfigurationProperties({ WebMvcProperties.class, ResourceProperties.class })
    public static class WebMvcAutoConfigurationAdapter
            implements WebMvcConfigurer, ResourceLoaderAware {

        private static final Log logger = LogFactory.getLog(WebMvcConfigurer.class);
        /**
        *静态资源位置定义:CLASSPATH_RESOURCE_LOCATIONS属性定义了默认的位置
        *   "classpath:/META-INF/resources/", 
        *   "classpath:/resources/",
        *   "classpath:/static/", 
        *   "classpath:/public/"
        **/
        //。。。。。。。。。。。省略代码。。。。。。。。。。。。。。。。。

        //默认静态资源实现核心代码,如果需要自己处理静态资源可以参考改代码
        @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));
            }
        }
        //。。。。。。。。。。。省略代码。。。。。。。。。。。。。。。。。

    }

通过代码分析默认配置/**的静态资源映射路径为:

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

通过debug发现最终的映射路径信息如下图所示:
这里写图片描述
根据以上图片得知,所有的映射路径最终都会加上”/”(注意:在使用配置文件时才会自动加上,或者覆写方法时参考底层实现),最终效果如下:

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

默认配置的 /webjars/** 映射到 classpath:/META-INF/resources/webjars/

注意:上面的 static、public、resources 等目录都在 classpath: 下面(如 src/main/resources/static)。资源映射的优先级顺序为:META-INF/resources > resources > static > public(可以放入同一个文件进行测试)。如果项目中没有对应的映射路径可以手动创建。

默认映射路径效果图如下:
这里写图片描述

优先级验证

分别在对应的映射路径中增加文件1.png,然后启动服务访问如下路径查看情况:

http://127.0.0.1:8080/1.png

默认配置文件显示测试,增加index.html文件

在static下面增加文件index.html,内容如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    映射目录测试!<br>
    <img alt="映射目录中都存在,但是图片信息不一样" src="http://localhost:8080/1.png"><br>
    <img alt="static下" src="http://127.0.0.1:8080/static1.png"><br>
    <img alt="resources下" src="resources1.png"><br>
    <img alt="public下" src="/public1.png"><br>
    <!-- <img alt="META-INF下" src="${rc.contextPath}/meta_inf_resources1.png"><br> -->
    <img alt="META-INF下" src="/meta_inf_resources1.png"><br>
</body>
</html>

自定义映射目录

默认情况下,SpringBoot从classpath下的/static(/public,/resources或/META-INF/resources)文件夹,或从ServletContext根目录提供静态内容。这是通过SpringMVC的ResourceHttpRequestHandler实现的,我们可以通过实现接口WebMvcConfigurer(注意在jdk1.8之前的版本中需要继承类WebMvcConfigurerAdapter)并实现addResourceHandlers方法来改变该行为(加载静态文件)或者通过修改配置文件来完成目录的映射。

修改默认映射

在src/main/resources/下创建一个文件夹view,并且创建文件index_view.html,使用以下方式使该文件能够正常访问。访问方式:

http://127.0.0.1:8080/index_view.html

实现接口

package com.sunld;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 自定义资源映射路径处理类
 * @author sunliaodong
 */
@Configuration
public class MyWebMvcConfigurer implements WebMvcConfigurer{

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        //将/** 目录下的静态资源映射到classpath:/view/下
        registry.addResourceHandler("/**").addResourceLocations("classpath:/view/");
    }
}

访问:

http://127.0.0.1:8080/index_view.html

可以正常访问,但是图片信息,获取不到,修改代码如下即可:

package com.sunld;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 自定义资源映射路径处理类
 * @author sunliaodong
 */
@Configuration
//增加该注解之后WebMvcAutoConfiguration中配置就不会生效
//@EnableWebMvc
public class MyWebMvcConfigurer implements WebMvcConfigurer{

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        /**
         * 将/** 目录下的静态资源映射到classpath:/view/下
         * 直接访问http://127.0.0.1:8080/index_view.html,发现图片信息获取不到需要增加默认的资源映射
         * Locations of static resources. Defaults to classpath:[/META-INF/resources/,
         * /resources/, /static/, /public/].
         */
        //
        registry.addResourceHandler("/**").addResourceLocations(
                "classpath:/META-INF/resources/", 
                "classpath:/resources/",
                "classpath:/static/", 
                "classpath:/public/",
                "classpath:/view/");
    }
}

修改配置文件

首先删除类MyWebMvcConfigurer。
在application.properties下添加如下信息:

#修改默认资源路径映射
# 默认值为 /**
spring.mvc.static-path-pattern=/**
# 默认值为 classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/ 
# 这里设置要指向的路径,多个使用英文逗号隔开,不影响默认的静态资源映射
spring.resources.static-locations=classpath:/view/

发现配置的view下的页面可以正常访问,以及/META-INF/resources/下的图片可以正常访问,其他默认的静态资源映射路径无法正常访问。按照以下方式修改配置文件即可

#修改默认资源路径映射
# 默认值为 /**
spring.mvc.static-path-pattern=/**
# 默认值为 classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/ 
# 这里设置要指向的路径,多个使用英文逗号隔开,不影响默认的静态资源映射
spring.resources.static-locations=classpath:/view/,classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/ 

增加新的映射

把view2/** 映射到classpath:/view/
访问方式:

http://127.0.0.1:8080/view2/index_view2.html

配置中配置了静态模式为/view2/,就只能通过/view2/来访问。

实现接口

package com.sunld;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 自定义资源映射路径处理类
 * @author sunliaodong
 */
@Configuration
//增加该注解之后WebMvcAutoConfiguration中配置就不会生效
//@EnableWebMvc
public class MyWebMvcConfigurer implements WebMvcConfigurer{

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        /**
         * 将/** 目录下的静态资源映射到classpath:/view/下
         * 直接访问http://127.0.0.1:8080/index_view.html,发现图片信息获取不到需要增加默认的资源映射
         * Locations of static resources. Defaults to classpath:[/META-INF/resources/,
         * /resources/, /static/, /public/].
         */
        registry.addResourceHandler("/**").addResourceLocations(
                    "classpath:/META-INF/resources/", 
                    "classpath:/resources/",
                    "classpath:/static/", 
                    "classpath:/public/",
                    "classpath:/view/");
        /**
         * 将/view2/** 目录映射到classpath:/view2下
         * 这种方式不影响springboot默认的静态资源映射路径,可以注释掉以上代码测试
         */
        registry.addResourceHandler("/view2/**").addResourceLocations(
                "classpath:/view2/");
    }
}

修改配置文件

首先删除类:MyWebMvcConfigurer然后修改配置文件

#增加新的资源路径映射
spring.mvc.static-path-pattern=/view2/**
spring.resources.static-locations=classpath:/view2/

发现默认的静态资源信息访问不到。

总结

修改默认的资源路径映射:

  • 修改配置文件,发现配置的view下的页面可以正常访问,以及/META-INF/resources/下的图片可以正常访问,其他默认的静态资源映射路径无法正常访问,可以在配置文件中加上即可。
  • 使用接口实现需要加入默认配置文件的映射路径,防止资源信息映射不到(默认的静态资源映射路径被覆盖)

添加新的资源路径映射:

  • 通过配置文件的方式会影响默认静态资源映射的访问(被覆盖)
  • 不影响默认静态资源的映射访问

总结

参考

Spring Boot干货系列:(六)静态资源和拦截器处理
Spring Boot 系列(四)静态资源处理
Spring Boot 静态资源处理
springboot搭建web(静态资源访问)(三)
Spring Boot - 静态资源处理、启动加载、日志处理

代码

https://github.com/sld880311/springboot-learning/tree/master/springboot_staticresource

猜你喜欢

转载自blog.csdn.net/sld880311/article/details/79460337
今日推荐