静态资源映射相关问题解答

    • [一、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 访问,都不可能通过地址栏拿到这个文件。

四、静态资源映射的安全注意事项

虽然不会泄露源代码,但静态资源映射还是有几个安全点要注意,不然容易出问题。

我们的经验是,先避开这几个坑:

  1. 别把敏感文件放进静态目录:比如数据库密码、接口密钥这些,要是放进 public 或者 static 里,别人就能直接下载。敏感文件一定要远离这些目录,配置信息最好加密存储。
  2. 外部路径映射别太大范围:别直接映射整个 D 盘或者 C 盘,比如只映射 D:/upload/,别写 file:D:/。可以加个路径校验,确保访问的文件都在允许的目录里。
  3. 限制上传文件类型:别让用户随便上传文件,尤其是 .jsp、.php 这类可执行文件,万一被上传到静态目录,可能会执行恶意代码。只允许业务需要的格式,比如 .ofd、.pdf、.jpg 。
  4. 别开启目录浏览:Spring Boot 默认是关闭目录浏览的,别手动开启。要是开启了,别人就能看到你静态目录里的所有文件结构,风险很高。
相关推荐
草履虫建模11 小时前
力扣算法 1768. 交替合并字符串
java·开发语言·算法·leetcode·职场和发展·idea·基础
qq_2975746713 小时前
【实战教程】SpringBoot 实现多文件批量下载并打包为 ZIP 压缩包
java·spring boot·后端
老毛肚13 小时前
MyBatis插件原理及Spring集成
java·spring·mybatis
学嵌入式的小杨同学13 小时前
【Linux 封神之路】信号编程全解析:从信号基础到 MP3 播放器实战(含核心 API 与避坑指南)
java·linux·c语言·开发语言·vscode·vim·ux
lang2015092813 小时前
JSR-340 :高性能Web开发新标准
java·前端·servlet
Re.不晚14 小时前
Java入门17——异常
java·开发语言
缘空如是14 小时前
基础工具包之JSON 工厂类
java·json·json切换
追逐梦想的张小年14 小时前
JUC编程04
java·idea
好家伙VCC14 小时前
### WebRTC技术:实时通信的革新与实现####webRTC(Web Real-TimeComm
java·前端·python·webrtc
南极星100515 小时前
蓝桥杯JAVA--启蒙之路(十)class版本 模块
java·开发语言