同事把配置文件放在源码的配置文件夹里,本地跑得好好的,打成一个可执行包丢到服务器就报文件找不到。这类路径问题在打包部署时集中爆发,搞清楚几种取路径的方式各自指哪,比反复试错省时间。

网页项目里取物理路径的办法

网页项目跑在容器里,可以用上下文取到项目在磁盘上的真实位置,再拼上网页目录得到发布目录的物理路径。它依赖容器,取到的是解压后的真实文件夹,上传文件存这里能直接被浏览器访问。但注意,打包成可执行包后,容器内资源在压缩包内部,这个方法可能取不到,会返回空,这也是线上突然读不到配置的常见原因。

读类路径资源更稳妥

配置文件、模板这类只读资源,用类加载器的资源流方式读取,它会从类路径里找,打没打包都能定位。注意加不加前导斜杠有区别,加了是从类路径根开始找,不加是从当前类的包里找,混用会找不到。读到的直接是输入流,配合缓冲流逐行读即可,用完及时关闭,不然句柄泄漏。

Spring项目里的三种写法

依赖注入一个资源加载器,用类路径前缀加文件名取资源,这是推荐写法。也可以用注解给字段注入资源,适合数量固定的配置文件。还有一种直接把类路径资源注入成可读对象,省去手写流处理。想批量加载,用通配符前缀匹配目录下的多个文件,按后缀过滤即可,比硬编码文件名灵活。

外置配置为什么更靠谱

运维改参数不该重新打包,所以生产环境把配置放到发布目录外,启动时用命令行指定路径或目录,Spring会优先读外部位置。打包内保留一份默认值兜底,外部有就用外部,没有就用内置。这样升级只换包,配置不用跟着动,回滚也简单。

  • 只读资源:优先用类路径流方式,打包后依然可用
  • 可写文件:上传目录用绝对路径配置,别依赖容器取路径
  • 排查口诀:包内找用流,磁盘写用绝对路径,线上一律外置优先
容器取真实路径: 上下文.getRealPath(网页目录)类路径流读取: 类对象.getResourceAsStream(斜杠加文件名)Spring注入: 注解加类路径前缀加文件名外置覆盖: 启动参数指定外部配置文件或目录