整合SpringMVC之静态资源配置

一.概述

我们在进行web开发的时候,一些静态资源的访问一般都是必需的,比如图片、js、css等资源的访问。在Spring Boot中对静态资源的访问实现了很好的支持,基本使用默认配置就能满足我们的开发需求。

1.默认的静态资源映射

Spring Boot中的Spring MVC模块利用ResourceHttpRequestHandler来处理静态内容,对静态资源的映射提供了默认的配置。默认情况下,SpringBoot按如下优先级,从上到下将 /** 所有的资源访问映射到以下目录:

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

如果我们在上面几个目录下存放同一份静态资源,比如在/static里面有个a.png,/public下面也有个a.png,则优先会加载/static下面的a.png。

对于资源目录下的资源,我们此时可以直接通过url地址访问http://localhost:8080/a.png,也就是说类似于以前web项目中的webapp目录,而放到其他目录下默认是无法被访问的。

为什么以上的几个文件夹,是Spring Boot中默认的存放静态资源的目录呢?我们可以看看addResourceHandlers()方法源码。

2.addResourceHandlers()源码

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(cachePerio))
       .setCacheControl(cacheControl));
    }
    //staticPathPattern的值是 /**
    String staticPathPattern = this.mvcProperties.getStaticPathPattern();
    if (!registry.hasMappingForPattern(staticPathPattern)) {
                customizeResourceHandlerRegistration(
                        registry.addResourceHandler(staticPathPattern)
    .addResourceLocations(getResourceLocations(
                                        this.resourceProperties.getStaticLocations()))
     .setCachePeriod(getSeconds(cachePeriod))
     .setCacheControl(cacheControl));
  }
}

从上面的源码中可以解读出两点关键信息:

  • 所有的"/webjars/**都去classpath:/META-INF/resources/webjars/路径下找静态资源;
  • 如果路径是/**时,就去以下路径加载资源。
classpath:/META-INF/resources/
classpath:/resources/
classpath:/static/
classpath:/public/

3.加载静态资源实验

为了验证上面的结论,我们可以创建一个新的web项目,做一个小实验,创建项目的过程参考之前的案例,此处略过。

在resources目录下分别新建resources、static、public、/META-INF/resources 4个目录,并分别放入a.png,b.png,c.png,d.png 4张图片。

项目结构图:

3.启动程序测试

我们在浏览器中,分别输入资源地址。

http://localhost:8080/a.png
可以看到如下效果:

http://localhost:8080/b.png

http://localhost:8080/c.png

http://localhost:8080/d.png

二.自定义静态资源访问路径

1.概述

我们除了可以把静态资源存放在默认的路径下之外,有时候我们也需要自定义静态资源的存放路径。

那么什么情况下,需要自定义静态资源存放路径呢?

比如我们开发一个项目,里面有文件上传功能,那么直接把上传的文件存放在上述那些文件夹中合适吗?

如果那样干的话,可能会存在如下问题:

  • 静态内容与项目代码不能有效分离;
  • 当项目被打包成一个.jar文件部署时,再将上传的文件放到这个.jar包中效率低下;
  • 备份网站数据的会很麻烦。

2.自定义位置的实现方式

那么此时我们能不能自定义静态资源的存放位置,把静态资源的访问路径映射到磁盘的某个目录里呢?这当然是可以的,接下来我们就讲解如何实现自定义静态资源的存放位置,我们有2种方式可以实现。

  • 代码中配置实现;
  • 配置文件配置实现;

接下来我们分别讲解两种实现方式。

3.代码中配置实现

这种方式中,需要我们自定义WebMvcConfigurerAdapter类,并覆写addResourceHandlers()方法来改变默认情况下加载静态文件的行为,这其实是通过Spring MVC的提供的ResourceHttpRequestHandler来实现的。

3.1 创建存放资源的目录

我们可以先在自己的某个盘符下创建一个资源文件夹,里面存放一些自己的资源,比如我的:

3.2 编写实现代码

因为在Spring Boot 2.x的版本中使用的是Spring5,WebMvcConfigurerAdapter已经过时,可以直接实现WebMvcConfigurer接口,或者继承WebMvcConfigurationSupport 类来代替,都要实现addResourceHandlers()方法。

package com.yyg.boot.config;

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

/**
 * @Description Description
 * @Author 一一哥Sun
 * @Date Created in 2020/3/21
 */
@Configuration
public class MyWebMvcConfig extends WebMvcConfigurationSupport {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        //将所有F:/resources/目录下的资源,访问时都映射到/res/** 路径下
        registry.addResourceHandler("/code/**")
                .addResourceLocations("classpath:/META-INF/resources/", "classpath:/resources/",
                "classpath:/static/", "classpath:/public/", "file:F:/resources/");
    }

}

注意:

当我们指定了静态文件目录之后,在页面中引用时,必须加上code,例如 等。

这其中的原因,可以去看看 WebMvcConfigurationSupport 和 WebMvcConfigurerAdapter 源码。

3.3 重新项目,访问测试

输入网址进行测试:
http://localhost:8080/code/logo02.png

此时只要我们在访问资源时,路径中匹配了“res”,就可以访问里面的资源。

4.配置文件设置实现

接下来我们讲解在properties配置文件中的实现方式。

注意:

记得我们把之前代码方式的实现先注释点,如果两种方式都配置的话,会以代码方式配置为准!

4.1 创建application.properties配置文件

内容如下:

#自定义的属性,指定了一个路径,注意要以/结尾
web.upload-path=F:/resources/

#表示所有的访问都经过静态资源路径
spring.mvc.static-path-pattern=/res/**

#配置所有的静态资源路径,要将默认的也加上否则static、public等这些路径将不能被当作静态资源路径.末尾是我们自己的自定义资源路径
spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,file:${web.upload-path}

注意:

  • web.upload-path:自定义属性,指定了我们静态资源的存放路径,注意要以/结尾;
  • spring.mvc.static-path-pattern=/**:表示所有的访问都经过静态资源路径的匹配规则;
  • spring.resources.static-locations:在这里配置静态资源路径,前面说了这里的配置是覆盖默认配置,所以需要将默认的也加上否则static、public等这些路径将不能被当作静态资源路径,在这个最末尾的file:${web.upload-path}之所有要加file:是因为指定的是一个具体的硬盘路径,其他的使用classpath指的是系统环境变量。

4.2 重启项目测试

输入网址,此时因为我的F:/resources/目录下有logo01.png资源,所以此时可以直接访问该资源。

http://localhost:8080/res/logo02.png

发布了412 篇原创文章 · 获赞 262 · 访问量 90万+

猜你喜欢

转载自blog.csdn.net/GUDUzhongliang/article/details/105651103