SpringBoot2.x系列教程10--SpringBoot中对静态资源文件的配置处理

简介: 前言在前面的章节中,壹哥 跟大家说过,现在Java中的项目,有的是前后端分离的,页面和静态资源都是分离出去的,与后端的Java代码都不在一起。当然也有一些前后端不分离的项目,页面和静态资源是与Java代码存放在一个jar或war包中的,那如果是SpringBoot开发的前后端不分离项目,对这些静态资源该如何处理呢?啥?你别告诉我,你连静态资源是什么都不知道哦!如果你对静态资源没有清晰的认识,那我就说一下吧。一般我们说的静态资源,指的是项目中用到的图片、js、css、纯html等资源。其实在SpringBoot中,对静态资源的访问有着比较好的支持,基本使用默认配置就能满足我们的开发需求

前言

在前面的章节中,壹哥 跟大家说过,现在Java中的项目,有的是前后端分离的,页面和静态资源都是分离出去的,与后端的Java代码都不在一起。当然也有一些前后端不分离的项目,页面和静态资源是与Java代码存放在一个jar或war包中的,那如果是SpringBoot开发的前后端不分离项目,对这些静态资源该如何处理呢?

啥?你别告诉我,你连静态资源是什么都不知道哦!

如果你对静态资源没有清晰的认识,那我就说一下吧。一般我们说的静态资源,指的是项目中用到的图片、js、css、纯html等资源。其实在SpringBoot中,对静态资源的访问有着比较好的支持,基本使用默认配置就能满足我们的开发需求了。

一. 静态资源处理机制简介

接下来 壹哥 就带大家学习一下SpringBoot中对静态资源的处理机制,看看SpringBoot对不同的静态资源是如何处理的,本章节的重点其实就是掌握静态资源的存储位置和加载路径。

1. 默认的静态资源映射

SpringBoot对Web的开发支持,主要是基于SpringMVC模块来实现的,而SpringMVC主要是利用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()源码

这是SpringBoot中的addResourceHandlers()源码方法。

publicvoidaddResourceHandlers(ResourceHandlerRegistryregistry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return;
    }
DurationcachePeriod=this.resourceProperties.getCache().getPeriod();
CacheControlcacheControl=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的值是 /**StringstaticPathPattern=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项目,带各位做一个小实验,创建项目的过程请参考之前的案例,此处略过。

4. 项目结构图

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

5. 启动项目测试

然后我们在浏览器中,分别输入各个静态资源的地址,这里我们直接通过URL地址即可访问不同的静态资源。

5.1 访问a.png

我们先来访问第一个图片a.png,地址如下:

http://localhost:8080/a.png

可以看到如下效果:

5.2 访问b.png

接下来再访问第2个图片b.png,地址如下:

http://localhost:8080/b.png

5.3 访问c.png

然后再访问第3个图片c.png,地址如下:

http://localhost:8080/c.png

5.4 访问d.png

最后再来访问第4个图片d.png,地址如下:

http://localhost:8080/d.png

最终我们会发现,这4个存放在不同位置下的静态资源,都可以被我们顺利的访问到。

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

1. 概述

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

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

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

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

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

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

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

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

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

3. 代码中配置实现

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

3.1 创建存放资源的目录

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

3.2 编写实现代码

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

packagecom.yyg.boot.config;
importorg.springframework.context.annotation.Configuration;
importorg.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
importorg.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
importorg.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
/*** @Description Description* @Author 一一哥Sun* @Date Created in 2020/3/21*/@ConfigurationpublicclassMyWebMvcConfigextendsWebMvcConfigurationSupport {
@OverridepublicvoidaddResourceHandlers(ResourceHandlerRegistryregistry) {
//将所有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

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

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

这时会发现我们的资源依然可以被访问到。

结语

至此,壹哥 就把SpringBoot中该如何存放和处理静态资源,详细的给各位讲解了,你可以按照我的讲解试试,把一些静态资源存放到不同的目录下,看看能不能正常访问到。

今日小作业:

把苍老师的靓照,通过今天的访问路径加载到themeleaf页面中显示出来。

相关文章
|
2月前
|
Cloud Native Java C++
Springboot3新特性:开发第一个 GraalVM 本机应用程序(完整教程)
文章介绍如何在Spring Boot 3中利用GraalVM将Java应用程序编译成独立的本机二进制文件,从而提高启动速度、减少内存占用,并实现不依赖JVM运行。
237 1
Springboot3新特性:开发第一个 GraalVM 本机应用程序(完整教程)
|
27天前
|
Java 应用服务中间件
SpringBoot获取项目文件的绝对路径和相对路径
SpringBoot获取项目文件的绝对路径和相对路径
64 1
SpringBoot获取项目文件的绝对路径和相对路径
|
21天前
|
网络协议 Java
springboot配置hosts文件
springboot配置hosts文件
44 11
|
2月前
|
XML Java Kotlin
springboot + minio + kkfile实现文件预览
本文介绍了如何在容器中安装和启动kkfileviewer,并通过Spring Boot集成MinIO实现文件上传与预览功能。首先,通过下载kkfileviewer源码并构建Docker镜像来部署文件预览服务。接着,在Spring Boot项目中添加MinIO依赖,配置MinIO客户端,并实现文件上传与获取预览链接的接口。最后,通过测试验证文件上传和预览功能的正确性。
springboot + minio + kkfile实现文件预览
|
27天前
|
存储 前端开发 JavaScript
|
27天前
|
存储 Java API
|
2月前
|
Java API Apache
Springboot+shiro,完整教程,带你学会shiro
这篇文章提供了一个完整的Apache Shiro与Spring Boot结合使用的教程,包括Shiro的配置、使用以及在非Web和Web环境中进行身份验证和授权的示例。
72 2
Springboot+shiro,完整教程,带你学会shiro
|
2月前
|
前端开发 Java Apache
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
本文详细讲解了如何整合Apache Shiro与Spring Boot项目,包括数据库准备、项目配置、实体类、Mapper、Service、Controller的创建和配置,以及Shiro的配置和使用。
375 1
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
|
2月前
|
easyexcel Java UED
SpringBoot中大量数据导出方案:使用EasyExcel并行导出多个excel文件并压缩zip后下载
在SpringBoot环境中,为了优化大量数据的Excel导出体验,可采用异步方式处理。具体做法是将数据拆分后利用`CompletableFuture`与`ThreadPoolTaskExecutor`并行导出,并使用EasyExcel生成多个Excel文件,最终将其压缩成ZIP文件供下载。此方案提升了导出效率,改善了用户体验。代码示例展示了如何实现这一过程,包括多线程处理、模板导出及资源清理等关键步骤。
|
28天前
|
Java
SpringBoot获取文件将要上传的IP地址
SpringBoot获取文件将要上传的IP地址
31 0