文件下载
这篇文档说明 Geelato 当前文件下载与预览能力的入口、运行方式,以及本地文件与 OSS 文件在下载时的差异。
本文主要基于:
DownloadControllerFileHandlerBaseHandlerAttachController
下载入口
当前最直接的下载入口是:
GET /api/resources/file
常用参数包括:
idisPdfisPreviewisThumbnail
其中:
id- 附件 ID
isPdf- 是否先转 PDF 再输出
isPreview- 是否以内联预览方式返回
isThumbnail- 是否优先下载缩略图
控制器本身很薄,核心逻辑都交给:
FileHandler.download(...)
下载时如何找到文件
下载不是直接根据路径拼接磁盘文件,而是先按附件 ID 查询附件元数据。
流程大致是:
- 根据附件 ID 查询
Attachment - 判断当前附件是否要切换到缩略图记录
- 判断该附件属于本地存储还是 OSS 存储
- 读取输入流或本地文件
- 按预览或下载方式回写响应
缩略图下载
如果:
isThumbnail=true
系统会优先查找该附件的子缩略图,并选择较小分辨率记录作为输出目标。
因此:
- 图片详情页
- 缩略列表页
可以共用同一套附件下载接口。
本地文件如何下载
当附件记录中:
objectId为空
系统会认为这是本地文件,然后直接使用:
Attachment.path
对应的本地路径读取文件。
这时的下载链路是:
- 把
path转成本地File - 必要时先做 PDF 转换
- 通过
DownloadService输出到响应流
OSS 文件如何下载
当附件记录中:
objectId非空
系统会认为附件位于 OSS。
这时不会直接访问本地磁盘,而是:
- 用
Attachment.path作为 OSS 对象名 - 调用
FileHelper.getFile(...) - 获取 OSS 输入流
- 再走统一下载输出逻辑
所以对于调用方来说:
- 下载接口保持不变
但底层读取来源会自动切换。
预览与下载的区别
下载链路里有一个很重要的参数:
isPreview
它控制当前输出更偏向:
- 浏览器直接预览
- 浏览器触发下载
底层实际输出由:
DownloadService.downloadFile(...)
负责处理响应头和内容流。
PDF 预览与格式转换
下载接口支持:
isPdf=true
这意味着:
- 先把原始文件转换成 PDF
- 再把 PDF 文件输出给浏览器
当前 PDF 转换能力由:
BaseHandler.toPdf(...)
负责,转换后的 PDF 临时文件会落到:
geelato.upload.convert-directory
对应的转换目录下。
这套机制适合:
- Office 文档在线预览
- Excel 转 PDF
- 统一浏览器端展示格式
此外,附件管理里还提供了:
GET /api/attach/toPdf/{id}
它会把 Excel 附件转换成新的 PDF 附件记录,并返回新附件 ID。
下载时的缓存控制
当前下载逻辑会在响应头里设置:
Cache-ControlETagLast-Modified
其中:
ETag使用附件 IDLast-Modified对本地文件取最后修改时间
这有助于浏览器和中间层做基础缓存控制。
配置文件下载
除标准附件外,还提供:
GET /api/resources/json
用于读取:
geelato.upload.config-directory
目录下的 .config 文件内容。
这通常用于:
- 站点配置读取
- 设计时 JSON 配置读取
- 运行时读取配置对象文件
附件管理相关接口
AttachController 除了元数据查询,也提供了多种和下载前后相关的辅助能力:
GET /api/attach/get/{id}POST /api/attach/image/{id}POST /api/attach/validPOST /api/attach/storage/{type}DELETE /api/attach/remove/{id}
其中:
valid- 用于校验附件物理文件是否仍可读取
storage/{type}- 用于在本地与 OSS 之间迁移存储
remove/{id}- 支持删除附件记录,并可选联动删除 OSS 文件
删除时的行为
当前删除能力支持:
- 只删除附件记录
- 删除附件记录时联动删除 OSS 文件
当传入:
deleteOss=true
并且该附件本身位于 OSS 时,系统会调用:
FileHelper.removeFile(...)
尝试把对象存储中的文件一起删除。
使用建议
- 业务前端下载统一使用附件 ID,不要直接暴露磁盘路径或 OSS 对象名
- 图片场景优先使用
isThumbnail降低带宽消耗 - 文档预览场景优先考虑
isPreview + isPdf - 如果附件会跨存储迁移,业务侧不要把
path当成稳定外链 - 如果要做严谨的文件生命周期治理,删除记录时应明确是否同步删除 OSS 对象