)
-
- [一、Spring Boot 默认能访问哪些静态资源?](#一、Spring Boot 默认能访问哪些静态资源?)
- [二、本地保存的文件,为什么不能通过 IP 访问?](#二、本地保存的文件,为什么不能通过 IP 访问?)
-
- [1. 本地测试用:把文件存到默认静态目录](#1. 本地测试用:把文件存到默认静态目录)
- [2. 生产通用:配置外部路径映射](#2. 生产通用:配置外部路径映射)
- 三、暴露静态目录,会泄露项目源代码吗?
- 四、静态资源映射的安全注意事项
做 Spring Boot 开发时,静态资源映射这块真的踩了不少坑。刚开始总搞不懂为什么服务器上能访问的文件,本地跑就报 404,也担心暴露目录会泄露源代码。今天把自己遇到的问题和解决办法整理下,都是实战里摸出来的经验,希望能帮到和我一样的新手。
一、Spring Boot 默认能访问哪些静态资源?
我一开始以为项目里所有文件都能通过 URL 直接访问,后来才发现不是这么回事。Spring Boot 有自己默认的静态资源目录,只有放在这些目录里的文件,不用写接口就能直接访问。
这些目录都在 src/main/resources/ 下面,按优先级从高到低排是这样的:
META-INF/resources/:一般用不上,大多是第三方插件放资源的地方resources/:自定义资源目录,我很少用static/:最常用的,我平时把图片、JS、CSS 都放这public/:和 static 功能差不多,优先级比 static 低一点
举个例子,把一张 test.png 图片放进 static/ 目录,启动项目后,直接在地址栏输 http://localhost:8080/test.png 就能打开。要是放进 static/img/ 里,路径就改成 http://localhost:8080/img/test.png 就行。
我认为这里有个关键点要注意:这些目录都是项目内的相对路径,不是本地磁盘的绝对路径。比如你把文件存在 D 盘根目录,哪怕路径写对了,默认也访问不到。
二、本地保存的文件,为什么不能通过 IP 访问?
先理清核心逻辑:文件保存到本地 / 服务器磁盘只是「物理存储」,但浏览器地址栏输入 URL 访问文件是「网络请求」------ 必须有一个「中间层」(Web 服务器 / 接口)把「磁盘文件路径」映射成「HTTP 可访问路径」,否则浏览器根本不知道如何访问本地文件。
这是我最开始踩的坑,做文件上传功能时,把文件保存到本地 D 盘的 upload 目录,返回的 URL 是 http://localhost:8080/files/test.ofd,但访问就是 404。可同样的代码部署到服务器,却能正常下载。
后来排查才知道,服务器上肯定配置了静态资源映射,把磁盘路径和 HTTP 路径关联起来了,而我本地只做了文件保存,没加这个配置。
在我看来,解决这个问题有两种办法,根据场景选就行。
1. 本地测试用:把文件存到默认静态目录
如果只是本地调试,不想改配置,可以把文件保存到 static 目录里。这样不用额外加代码,就能直接访问。
代码示例大概是这样的:
java
// 获取 static 目录的绝对路径
String fileSavePath = new ClassPathResource("static/").getFile().getAbsolutePath() + "/OFD_File/";
// 上传后的文件会存在 src/main/resources/static/OFD_File/ 下面
// 访问路径就是 http://localhost:8080/OFD_File/xxx.ofd
不过这个方法只适合测试,我们的经验是,项目重新编译或者重启后,static 目录里的上传文件会丢失,生产环境绝对不能用。
2. 生产通用:配置外部路径映射
这是最稳妥的方式,不管本地还是服务器都能用。核心就是写个配置类,把外部磁盘路径映射成 HTTP 能访问的路径。
我常用的配置代码是这样的:
java
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
// 本地磁盘文件保存路径(建议写在配置文件里,用 @Value 注入)
private String externalFilePath = "file:D:/upload/";
// 对外暴露的访问前缀
private String accessPrefix = "/files/";
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// 把 /files/** 路径映射到本地 D:/upload/ 目录
registry.addResourceHandler(accessPrefix + "**")
.addResourceLocations(externalFilePath);
}
}
配置完之后,文件保存到 D:/upload/OFD_File/xxx.ofd,访问路径就是 http://localhost:8080/files/OFD_File/xxx.ofd,和服务器端的逻辑完全一致。
这里有个踩坑点要提醒下:路径必须以 file: 开头,Windows 系统要用 /分隔,别用 \,不然会被转义导致映射失败。
三、暴露静态目录,会泄露项目源代码吗?
刚开始用 public、static 这些目录时,我特别担心会不会把 Java 源代码暴露出去,后来自己测试过才放心。
我认为完全不用怕,Spring Boot 只会暴露这些目录里的静态文件,源代码根本不会被访问到。
原因很简单:我们写的 Java 代码在 src/main/java/ 目录下,编译后变成 .class 文件,也不在 static、public 这些目录里。浏览器访问时,Spring Boot 只会找静态资源目录里的文件,根本不会管 .java 或者 .class 文件。
比如你在 src/main/java/ 下写了一个 TestController.java,不管用什么 URL 访问,都不可能通过地址栏拿到这个文件。
四、静态资源映射的安全注意事项
虽然不会泄露源代码,但静态资源映射还是有几个安全点要注意,不然容易出问题。
我们的经验是,先避开这几个坑:
- 别把敏感文件放进静态目录:比如数据库密码、接口密钥这些,要是放进 public 或者 static 里,别人就能直接下载。敏感文件一定要远离这些目录,配置信息最好加密存储。
- 外部路径映射别太大范围:别直接映射整个 D 盘或者 C 盘,比如只映射 D:/upload/,别写 file:D:/。可以加个路径校验,确保访问的文件都在允许的目录里。
- 限制上传文件类型:别让用户随便上传文件,尤其是 .jsp、.php 这类可执行文件,万一被上传到静态目录,可能会执行恶意代码。只允许业务需要的格式,比如 .ofd、.pdf、.jpg 。
- 别开启目录浏览:Spring Boot 默认是关闭目录浏览的,别手动开启。要是开启了,别人就能看到你静态目录里的所有文件结构,风险很高。