PreviewDownloadController(预览/下载)¶
cn.myapps.converter.controller.PreviewDownloadController
预览与下载控制器,提供转换后文件的存在性校验、KMS 转换文件下载、runtime 预览格式下载(含文件加密检测与解密、路径规范化与目录穿越防护)。基址为 converter 模块的 context-path 占位符 ${myapps.context-path.converter:}(无 /api/rest 前缀)。
- 接口类型:REST 资源
- 类级注解:
@RestController、@Tag(name = "Preview控制器") - 基址:
${myapps.context-path.converter:} - 鉴权:见 index.md 鉴权说明(无 token 强校验;但下载类端点需携带 accessToken 以派生 DES 解密密钥)
1. 校验文件是否存在¶
校验指定相对路径下的文件是否存在,含目录穿越防护(必须位于 <storageRoot>/uploads/ 规范路径下)。
- 接口类型:REST 资源
- 请求方式:
GET - 请求路径:
/api/preview/isFileExisted(完整:${myapps.context-path.converter:}/api/preview/isFileExisted) - 鉴权:否(无 token 强校验)
- Tag:Preview控制器
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| filepath | query | string | 是 | 文件相对路径,将以 ISO-8859-1 解码后拼接到 Environment.getStorageRootPath() 之后;若已加密会先解密 |
请求示例¶
响应¶
结构:统一 Resource(见 ../index.md「统一响应结构」)。data 恒为 null,信息在 errmsg。注意 errcode 取值非标(200=成功、500=各类失败)。
| errcode | errmsg | 含义 |
|---|---|---|
| 200 | 文件存在! | 文件存在 |
| 500 | 编码类型错误! | URLDecoder 不支持 ISO-8859-1 |
| 500 | 文件路径或类型不合法! | 解析后路径不在 <storageRoot>/uploads/ 规范目录下 |
| 500 | 文件不存在! | 文件不存在 |
成功示例:
失败示例:
2. KMS 转换文件下载¶
下载 KMS 主题转换后的目标文件(路径位于 <storageRoot>/convert/pdf/kms/.objects/)。响应为二进制流。
- 接口类型:REST 资源(二进制响应)
- 请求方式:
GET - 请求路径:
/api/kms/converted/download(完整:${myapps.context-path.converter:}/api/kms/converted/download) - 鉴权:见 index.md 鉴权说明(需 accessToken:filepath 经
DesUtil.decryptTextByUserId(filepath, getUserId(request))解密,userId 取自Security.getUserIdFromToken(request)) - Tag:Preview控制器
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| filepath | query | string | 是 | 已加密的文件相对路径;先用当前用户 id 作为 DES 密钥解密,再拼接到 <storageRoot>/convert/pdf/kms/.objects/ 之后 |
| filename | query | string | 是 | 文件名(含扩展名),用于推导目标扩展名、设置响应 MIME 与下载文件名 |
| watermarkStr | query | string | 否 | 水印文本(参数声明但当前实现未实际写入水印) |
请求示例¶
响应¶
结构:二进制流(成功时由 FileUtil.getMimeType(realFilePath) 推断 Content-Type,如 application/pdf;响应体为文件字节流)。
失败示例(写入纯文本错误,HTTP 状态仍 200):
或| 触发条件 | 响应体文本 |
|---|---|
解析后路径不在 <storageRoot>/convert/pdf/ 规范目录下 |
Error: file path illegal! |
| 文件不存在 | 找不到指定文件 |
文件名包含特殊符号(SecurityURL.simpleSpecialSymbols(filename) 校验失败) |
空响应体(不下发) |
路径安全:实现使用
SecurityFile.resolveFile(...).getCanonicalFile()与convert/pdf/规范目录前缀比对,避免目录穿越;若文件已加密(FileEncryptAndDecrypt.isEncrypt),先解密到临时文件再输出,输出完成后删除解密临时文件。
3. Runtime 预览格式下载¶
下载 runtime 主题转换后的目标文件(路径位于 <storageRoot>/convert/pdf/)。响应为二进制流。
- 接口类型:REST 资源(二进制响应)
- 请求方式:
GET - 请求路径:
/api/runtime/converted/download(完整:${myapps.context-path.converter:}/api/runtime/converted/download) - 鉴权:见 index.md 鉴权说明(需 accessToken:filepath 经
DesUtil.decryptTextByUserId(filepath, getUserId(request))解密,userId 取自Security.getUserIdFromToken(request)) - Tag:Preview控制器
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| filepath | query | string | 是 | 已加密的文件相对路径;先用当前用户 id 作为 DES 密钥解密,再拼接到 <storageRoot>/convert/pdf/ 之后 |
| filename | query | string | 是 | 文件名(含扩展名),用于推导目标扩展名、设置响应 MIME 与下载文件名 |
| watermarkStr | query | string | 否 | 水印文本(参数声明但当前实现未实际写入水印) |
请求示例¶
响应¶
结构:二进制流(成功时 Content-Type 由 FileUtil.getMimeType(realFilePath) 推断;响应体为文件字节流)。
失败示例(写入纯文本错误,HTTP 状态仍 200):
或| 触发条件 | 响应体文本 |
|---|---|
解析后路径不在 <storageRoot>/convert/pdf/ 规范目录下 |
Error: file path illegal! |
| 文件不存在 | 找不到指定文件 |
| 文件名包含特殊符号 | 空响应体(不下发) |
该端点与
doFileDownload(KMS)逻辑结构相同,区别仅在于文件落盘目录:本端点为<storageRoot>/convert/pdf/<filepath>,KMS 端点为<storageRoot>/convert/pdf/kms/.objects/<filepath>。