外观
资源文件重点文件与方法
从上传门面到文件记录、存储路由和访问签名逐层说明。各供应商的实际能力、配置和回调安全边界见存储配置与访问与上传与直传签名。
本页按重点文件查阅方法;表内方法名可打开源码。重载共享的约束写在表前,差异在各行说明。源码链接固定到核对版本,接入前提见快速开始。
ResourceService
源码:ResourceService;实现:ResourceServiceImpl。
应用优先注入的上传门面。method 是配置源名称,省略时取默认源。所有 upload 最终返回文件记录 VO,signature 返回签名或已命中记录;未知 method 可能回退默认源。
| 方法 / 重载 | 用途、参数与返回值 | 注意事项 |
|---|---|---|
| signature(String method, String fileName) | 无额外配置签发上传参数,默认日期目录、随机文件名。 | 不是上传或入库;源不支持签名时抛业务异常。 |
| signature(String method, String fileName, UploadFileForSignatureCommonConfig form) | 支持 MD5 复用、目录和随机名配置。 | form=null 走默认命名;有 MD5 时受当前必取查询缺陷影响,见下方 FileRecordService。 |
| upload(String method, UploadModel file, UploadModelConfig config) | 按唯一性策略查询记录,再设置 position/日期目录、按配置改名、上传并登记。 | config 非 null;上传和落库没有分布式事务,失败可能留下对象。 |
| upload(String method, UploadModel file) | 使用 UploadModelConfig.DEFAULT。 | 默认随机名策略;传入 UploadModel 会被修改并在记录构建时关闭。 |
| upload(UploadModel file) | 默认源上传,返回 FileRecordVo。 | 不能只靠调用成功判断真实对象存在,需注意适配器吞异常行为。 |
| upload(String method, MultipartFile file) | 将 MultipartFile 包装为 UploadModel 后上传到指定源。 | 读取文件及 MD5 有 IO 和内存成本。 |
| upload(MultipartFile file) | 选择默认源再调用指定源重载。 | 不声明按当前用户隔离上传目录。 |
| upload(String method, File file) | 将 File 包装为 UploadModel 后上传到指定源。 | 读取文件及 MD5 有 IO 和内存成本。 |
| upload(File file) | 选择默认源再调用指定源重载。 | 不声明按当前用户隔离上传目录。 |
| upload(String method, String path) | 将 String 包装为 UploadModel 后上传到指定源。 | String 是路径,不是待上传文本。 |
| upload(String path) | 选择默认源再调用指定源重载。 | 不声明按当前用户隔离上传目录。 |
| upload(String method, String path, UploadModelConfig config) | 路径包装为 UploadModel,用指定源和配置上传。 | 路径需受控;配置不改变全局 MD5 唯一策略。 |
| upload(String path, UploadModelConfig config) | 默认源、指定路径和配置。 | 失败资源清理由调用流程和适配器共同决定。 |
| upload(String method, List<UploadModel> files) | 按输入顺序逐项上传,返回 List<FileRecordVo>。 | 非空集合/数组,元素需有效;中途失败不回滚之前的对象或记录。 |
| upload(List<UploadModel> files) | 默认源批量上传,返回对应记录列表。 | 不是原子批量;每项都执行单条流程。 |
| upload(String method, MultipartFile[] files) | 按输入顺序逐项上传,返回 List<FileRecordVo>。 | 非空集合/数组,元素需有效;中途失败不回滚之前的对象或记录。 |
| upload(MultipartFile[] files) | 默认源批量上传,返回对应记录列表。 | 不是原子批量;每项都执行单条流程。 |
| upload(String method, File[] files) | 按输入顺序逐项上传,返回 List<FileRecordVo>。 | 非空集合/数组,元素需有效;中途失败不回滚之前的对象或记录。 |
| upload(File[] files) | 默认源批量上传,返回对应记录列表。 | 不是原子批量;每项都执行单条流程。 |
| upload(String method, String[] pathList) | 按输入顺序逐项上传,返回 List<FileRecordVo>。 | 非空集合/数组,元素需有效;中途失败不回滚之前的对象或记录。 |
| upload(String[] pathList) | 默认源批量上传,返回对应记录列表。 | 不是原子批量;每项都执行单条流程。 |
ResourceServiceImpl
本文件只实现完整 signature 与 upload 两个入口;便捷重载在 ResourceService 内。
| 方法 / 重载 | 用途、参数与返回值 | 注意事项 |
|---|---|---|
| signature(String method, String fileName, UploadFileForSignatureCommonConfig form) | 先尝试同源 MD5 复用,再按目录、日期、随机名生成对象键并委托适配器。 | FileRecordService 当前未命中抛异常;不是“查不到就总能继续签名”。 |
| upload(String method, UploadModel file, UploadModelConfig config) | UNIQUE 全局查 MD5;NEXT 按源唯一设置查;REPEAT 跳过复用后上传并登记。 | 当前快速开始使用 REPEAT;成功上传但写库失败没有补偿事务。 |
以下代码放入已注入 ResourceService resources 的后台方法;import 为 java.io.File,文件需实际存在且已配置可用源:
java
var record = resources.upload("default", new File("/srv/app/export/report.csv"));
Long fileId = record.getId(); // 文件记录 ID,用于关联业务对象
// 实际公网/私有访问地址按存储配置构造,不能把 fileId 当对象键。FileRecordService
源码:FileRecordService;实现:FileRecordServiceImpl。
保存文件元数据,继承通用 CRUD。md5Expire 单位为天,按本地日期减天数限定 createTime 下界;null 表示不限制时间,0 表示今天起。position 为空白时不限制源。
| 方法 / 重载 | 用途、参数与返回值 | 注意事项 |
|---|---|---|
| afterUpload(FileRecord po) | 委托 addByPo,返回单条 FileRecordVo。 | 只登记,不重复上传;单条路径会运行保存路径处理器。 |
| afterUpload(List<FileRecord> poList) | 委托 addBatchByPoList,返回列表。 | 不逐项调用单条路径处理器,且当前受 MapperUtil 未执行惰性回调问题影响。 |
| getPoByMd5(String md5) | 按 MD5 返回 FileRecord;不限源与创建时间。 | 单条实际 getPoByWrapper,未命中抛 business_not_found,多条匹配也可能抛异常;不能依赖 null。 |
| getPoByMd5(String md5, String position) | 按 MD5 返回 FileRecord;按非空白 position 限源,不限时间。 | 单条实际 getPoByWrapper,未命中抛 business_not_found,多条匹配也可能抛异常;不能依赖 null。 |
| getPoByMd5(String md5, String position, Integer md5Expire) | 按 MD5 返回 FileRecord;可同时限定源和创建时间。 | 单条实际 getPoByWrapper,未命中抛 business_not_found,多条匹配也可能抛异常;不能依赖 null。 |
| getByMd5(String md5) | 按 MD5 返回 FileRecordVo;不限源与创建时间。 | 单条实际 getPoByWrapper,未命中抛 business_not_found,多条匹配也可能抛异常;不能依赖 null。 |
| getByMd5(String md5, String position) | 按 MD5 返回 FileRecordVo;按非空白 position 限源,不限时间。 | 单条实际 getPoByWrapper,未命中抛 business_not_found,多条匹配也可能抛异常;不能依赖 null。 |
| getByMd5(String md5, String position, Integer md5Expire) | 按 MD5 返回 FileRecordVo;可同时限定源和创建时间。 | 单条实际 getPoByWrapper,未命中抛 business_not_found,多条匹配也可能抛异常;不能依赖 null。 |
| listPoByMd5(String md5) | 按 MD5 返回 List<FileRecord>;不限源与创建时间。 | 无匹配返回空列表;VO 是 PO 转换结果。 |
| listPoByMd5(String md5, String position) | 按 MD5 返回 List<FileRecord>;按非空白 position 限源,不限时间。 | 无匹配返回空列表;VO 是 PO 转换结果。 |
| listPoByMd5(String md5, String position, Integer md5Expire) | 按 MD5 返回 List<FileRecord>;可同时限定源和创建时间。 | 无匹配返回空列表;VO 是 PO 转换结果。 |
| listByMd5(String md5) | 按 MD5 返回 List<FileRecordVo>;不限源与创建时间。 | 无匹配返回空列表;VO 是 PO 转换结果。 |
| listByMd5(String md5, String position) | 按 MD5 返回 List<FileRecordVo>;按非空白 position 限源,不限时间。 | 无匹配返回空列表;VO 是 PO 转换结果。 |
| listByMd5(String md5, String position, Integer md5Expire) | 按 MD5 返回 List<FileRecordVo>;可同时限定源和创建时间。 | 无匹配返回空列表;VO 是 PO 转换结果。 |
| listPoByMd5(Collection<String> md5List) | 按 MD5 返回 List<FileRecord>;不限源与创建时间。 | md5List=null/空返回空;结果按创建时间倒序,不保持输入顺序。 |
| listPoByMd5(Collection<String> md5List, String position) | 按 MD5 返回 List<FileRecord>;按非空白 position 限源,不限时间。 | md5List=null/空返回空;结果按创建时间倒序,不保持输入顺序。 |
| listPoByMd5(Collection<String> md5List, String position, Integer md5Expire) | 按 MD5 返回 List<FileRecord>;可同时限定源和创建时间。 | md5List=null/空返回空;结果按创建时间倒序,不保持输入顺序。 |
| listByMd5(Collection<String> md5List) | 按 MD5 返回 List<FileRecordVo>;不限源与创建时间。 | md5List=null/空返回空;结果按创建时间倒序,不保持输入顺序。 |
| listByMd5(Collection<String> md5List, String position) | 按 MD5 返回 List<FileRecordVo>;按非空白 position 限源,不限时间。 | md5List=null/空返回空;结果按创建时间倒序,不保持输入顺序。 |
| listByMd5(Collection<String> md5List, String position, Integer md5Expire) | 按 MD5 返回 List<FileRecordVo>;可同时限定源和创建时间。 | md5List=null/空返回空;结果按创建时间倒序,不保持输入顺序。 |
FileRecordServiceImpl
实现三个 MD5 数据查询,并覆盖单条 addByPo。路径处理器在初始化时按 sequence 排序加入静态列表,不是每次请求重新发现。
| 方法 / 重载 | 用途、参数与返回值 | 注意事项 |
|---|---|---|
| getPoByMd5(String md5, String position, Integer md5Expire) | 按 MD5、可选源与日期筛选,创建时间倒序,执行单条必取。 | 没有 LIMIT 1,排序不等于“只取最新一条”。 |
| listPoByMd5(String md5, String position, Integer md5Expire) | 同样条件的 PO 列表查询。 | 可匹配多个重复上传记录。 |
| listPoByMd5(Collection<String> md5List, String position, Integer md5Expire) | 按 MD5 IN 集合查询,空集合提前返回空。 | 不是逐输入 MD5 返回固定数量结果。 |
| addByPo(FileRecord fileRecord) | 保存处理开启且 path 尚未含指定 params 时,依序调用路径处理器,再通用插入。 | path/config 需有效;只影响该单条入口,批量路径不会自动复用。 |
ResolveObjectStoreUtil
初始化后通过静态映射选择对象存储工具。工具由反射 new,不是普通 Spring Bean;不要依赖工具字段自动注入。
| 方法 / 重载 | 用途、参数与返回值 | 注意事项 |
|---|---|---|
| get() | 返回默认工具。 | 没有有效默认源可能 null。 |
| get(String name) | 优先命名源,未知名称回退默认工具。 | 不是严格源名校验,不能用于租户隔离。 |
| listByServiceName(String serviceName) | 返回某供应商的工具列表,缺失空列表。 | serviceName 不是 method;同供应商多源回调需明确路由。 |
| defaultMethodName() | 默认工具存在则取其 name,否则字符串 default。 | 字符串 default 不保证对应已注册有效工具。 |
| getSourcePropertyByPosition(String position) | 按 position 查源属性,缺失 null。 | 同 position 配置冲突会覆盖映射。 |
| getSourcePropertyByPath(String path) | 从 URI 提取 origin,再查源属性。 | 相对对象键一般无法识别为私有源。 |
| getUtilByPath(String path) | 按路径 origin 找 method,再 get(method)。 | 未知路径可能回退默认工具,不应推断源已匹配。 |
| handleAvailablePath(String path) | 同地域时把外网 endpoint 文本替换为内网 endpoint。 | 不执行网络探测;依赖正确的源属性与地域标记。 |
| getMethodByPosition(String position) | 返回配置源名称,未知 null。 | 不回退默认名称。 |
| init() | 加载 source/multiple-source/primary,建立路径和供应商索引。 | 生命周期方法不用于运行期重复刷新;无配置回退本地存在未初始化属性问题,见配置页。 |
| getViewPositionMap() | 返回原地址到展示地址映射。 | 内部可变静态 Map,不要由业务请求修改。 |
| getViewPositionSaveMap() | 返回展示地址到保存地址映射。 | 仅配置映射,不迁移已有文件。 |
BaseObjectStoreUtil
适配器基础上传契约,直接调用时不自动保存 FileRecord。列表上传在这里是 parallelStream,与 ResourceService 顺序批量不同。
| 方法 / 重载 | 用途、参数与返回值 | 注意事项 |
|---|---|---|
| uploadFile(T file) | 由实现上传并返回模型。 | 必须核对供应商的异常传播和流关闭行为。 |
| uploadFile(T file, Consumer<T> then) | 单条上传后调用 then,再返回模型。 | 回调失败不自动删除上传对象。 |
| uploadFile(List<T> fileList) | 并行上传列表并返回结果。 | 失败时其他并行上传可能仍在运行,非原子批量。 |
| uploadFile(List<T> fileList, Consumer<List<T>> then) | 列表完成后将结果交给回调。 | 回调不是事务提交事件。 |
| check() | 默认 true,供初始化校验覆盖。 | 默认值不证明配置和远端连接有效。 |
| uploadPath() | 默认空字符串,供源访问位置拼接。 | 与本地文件保存目录不是必然相同概念。 |
| restore(String path) | 默认抛 UnsupportedOperationException("restore")。 | 需要恢复能力时明确实现。 |
| position() | 返回存储访问位置字符串。 | 不是授权后的私有读取 URL。 |
AbstractObjectStoreUtil
各供应商工具共同父类;继承 BaseObjectStoreUtil。Lombok 生成 name/properties/isSameRegion 的 getter,初始化前可能未赋值。
| 方法 / 重载 | 用途、参数与返回值 | 注意事项 |
|---|---|---|
| serviceName() | 子类返回供应商标识。 | 用于回调分组,不是命名源 key。 |
| init(String name, ResourceSourceProperty sourceProperty) | 设置名称和属性,check=false 返回 null,否则计算同地域后返回自身。 | 并未把反射创建对象注册成 Spring Bean。 |
| signature(String uri) | 默认抛 SIGNATURE_UNDEFINED。 | 只有支持此能力的适配器可签名。 |
| temporaryAccessPath(String path) | 默认委托 3600 秒、无样式。 | 子类最终实现决定是否生成签名。 |
| temporaryAccessPath(String path, String style) | 默认委托 3600 秒、指定样式。 | 这个重载不读取业务 property.privateReadExpire。 |
| temporaryAccessPath(String path, long expiration, String style) | 默认原样返回 path。 | 默认不是私有读签名,不能仅开 private-read 就获得能力。 |
| position() | 属性缺失返回 localhost,否则 position+uploadPath。 | 字符串拼接,不执行 URL 可用性验证。 |
| checkUploadCallBack(HttpServletRequest request, String body) | 默认 true。 | 只有实际重写验签的适配器才证明来源可信;不能把此默认方法当安全验证。 |
ResourceTemporaryAccessUtil
源码:ResourceTemporaryAccessUtil。
先按完整 URL 识别源属性;非私有或未识别返回原路径。私有路径签名缓存键只包含 path+style 的 MD5,不含 method/expiration/userId,不能承担授权隔离。
| 方法 / 重载 | 用途、参数与返回值 | 注意事项 |
|---|---|---|
| getTemporaryAccessPath(String method, String path) | 默认有效期、无样式,返回地址 String。 | expiration=null/非正使用源配置;已有缓存可能沿用此前不同的有效期。 |
| getTemporaryAccessPath(String method, String path, Long expiration) | 指定有效秒数、无样式,返回地址 String。 | expiration=null/非正使用源配置;已有缓存可能沿用此前不同的有效期。 |
| getTemporaryAccessPath(String method, String path, String style) | 默认有效期、指定样式,返回地址 String。 | expiration=null/非正使用源配置;已有缓存可能沿用此前不同的有效期。 |
| getTemporaryAccessPath(String method, String path, Long expiration, String style) | 指定有效秒数与样式,返回地址 String。 | expiration=null/非正使用源配置;已有缓存可能沿用此前不同的有效期。 |
| getTemporaryAccessPathMap(String method, Collection<String> pathList) | 默认有效期、无样式,返回原地址到访问地址的 Map。 | parallelStream 并行;重复 path 会造成 toConcurrentMap 重复键异常,先去重。 |
| getTemporaryAccessPathMap(String method, Collection<String> pathList, Long expiration) | 指定有效秒数、无样式,返回原地址到访问地址的 Map。 | parallelStream 并行;重复 path 会造成 toConcurrentMap 重复键异常,先去重。 |
| getTemporaryAccessPathMap(String method, Collection<String> pathList, String style) | 默认有效期、指定样式,返回原地址到访问地址的 Map。 | parallelStream 并行;重复 path 会造成 toConcurrentMap 重复键异常,先去重。 |
| getTemporaryAccessPathMap(String method, Collection<String> pathList, Long expiration, String style) | 指定有效秒数与样式,返回原地址到访问地址的 Map。 | parallelStream 并行;重复 path 会造成 toConcurrentMap 重复键异常,先去重。 |
FileRecordUtil
源码:FileRecordUtil。
把上传模型转换成文件记录并关闭模型资源,或拆分 HTTP 访问路径。
| 方法 / 重载 | 用途、参数与返回值 | 注意事项 |
|---|---|---|
| build(BaseUploadModel file) | 先 file.close(),再构建 FileRecord。 | 调用后不能继续使用已关闭流;并不插入数据库。 |
| build(List<BaseUploadModel> fileList) | 逐项关闭并转换,返回记录列表。 | 中途异常不保证剩余模型已关闭。 |
| getPosition(String uri) | 提取以 http 开头的 URI 域名前缀,否则 null。 | 简单字符串处理,不是严格 URL 校验;null 会失败。 |
| getPath(String uri) | 提取 HTTP(S) 路径并去掉开头 /,匹配时不包含 query/fragment。 | 相对路径原样处理后去掉一个前导 /;不是授权校验。 |
AppResourceController
HTTP 前缀 /api/app/resource;整个类标 @LoginIgnore。上传和签名开放范围、配额及业务归属由应用限制,不能根据 App 字样假定必须登录。
| 方法 / 重载 | 用途、参数与返回值 | 注意事项 |
|---|---|---|
| upload(String method, MultipartFile file) | POST /upload,multipart 的 file;method 默认 default,data 为单个 VO。 | 只上传一项;源回退和 MD5 策略同服务。 |
| upload(String method, MultipartFile[] files) | POST /batch/upload,multipart 的 files,data 为 VO 列表。 | 顺序逐个调用,失败不回滚前项。 |
| signature(String method, String fileName, String md5, Integer md5Expire) | GET /signature,query 参数,返回 SignatureModelShowVo。 | 存在复用结果和签名结果两种情况。 |
| signature(String method, String fileName, UploadFileForSignatureCommonConfig config) | GET /signature/common,同时需要 JSON 请求体和 query 参数。 | 代理/客户端可能不支持 GET body;须按当前接口验证。 |
| signatureForBusiness(String fileName, UploadFileForSignatureConfig config) | POST /signature,按 module/sign Hook 路由源。 | 路由不是用户权限验证。 |
| uploadCallback(String serviceName, String body) | POST /upload/callback/{serviceName},选择供应商第一工具校验,解析并登记。 | body 是 URL 编码文本不是 JSON;默认验签放行和重复回调风险见上传页。 |
私有 resolveBodyToFileRecordDto 按 & 与 = 拆分,将大写下划线字段转小驼峰并 URL 解码;值内特殊字符必须编码,否则可能被截断/忽略。
AdminFileRecordController
HTTP 前缀 /api/admin/file/record,ResultModel 包装结果。类声明模块标记,方法未逐个标 PermissionOperation,具体保护需核实应用安全规则。
| 方法 / 重载 | 用途、参数与返回值 | 注意事项 |
|---|---|---|
| page(FileRecordQuery query) | POST /page;data 为 PageModel<FileRecordVo>。 | 当前通用 Query 字段是否生效见记录管理页。 |
| add(FileRecordDto dto) | POST /;dto.check 后登记已有对象信息。 | 不上传、不验证对象存在。 |
| getById(Long fileId) | GET /{fileId},必取记录 VO。 | 缺失抛 business_not_found。 |
| delete(Long fileId) | DELETE /{fileId},data=true。 | 物理删除记录,不删对象文件;未校验引用关系。 |
| batchDelete(String fileIds) | DELETE /batch/{fileIds},逗号分隔 Long ID,data=true。 | 非数字转换失败;不逐条执行单删钩子,不删除对象。 |