文档解析
受众:开发者 摘要:Document starter 使用方式、抽象边界、配置、plain-text provider 和 Tika 富文档 provider。
Document starter 提供统一的文档文本抽取抽象,用于后续知识库、搜索、AI 任务、附件索引和内容导入。
第一阶段保持轻量:内置 plain-text provider 和 tika provider。plain-text 支持文本、Markdown、HTML、CSV、JSON、XML、YAML 和日志类文件;tika 支持 PDF、Office、RTF 和 OpenDocument 等常见富文档。OCR 等能力后续通过独立 provider 或异步任务接入,不把第三方 API 泄露给业务模块。
何时使用
适合:
- 从上传文件、附件或 Storage 文件中抽取文本。
- 给 Search / Knowledge / AI Task 提供统一文本来源。
- 对文档解析设置统一大小、文本长度和 provider 边界。
不适合:
- 直接替代 Storage 文件权限。
- 在同步接口中处理超大文件、批量文件或 OCR。
- 让业务模块直接依赖 Tika、PDFBox、POI 等第三方解析 API。
快速开始
按需引入:
<dependency>
<groupId>com.springopen</groupId>
<artifactId>spring-open-starter-document</artifactId>
</dependency>启用:
spring:
open:
document:
enabled: true
default-provider: plain-textFacade 使用:
DocumentExtractResult result = Document.extract(
DocumentSource.text("readme.md", "# Hello"));
String text = result.getText();也可以显式传入选项:
DocumentExtractResult result = Document.extract(
DocumentSource.bytes("data.json", "application/json", bytes),
DocumentExtractOptions.builder()
.maxTextLength(20_000)
.extractMetadata(true)
.build());机制说明
Document starter 的核心边界是 Facade + Manager + Provider:
Document是业务侧入口,不直接依赖第三方解析库。DefaultDocumentManager合并调用选项、全局配置和 provider 配置;大小、文本长度等限制取更严格的正数值。DocumentProviderCatalog提供只读 provider 目录快照,供 Admin 运维页、文档导出或 smoke 检查展示当前解析能力、启用状态和有效限制。DocumentProvider只负责具体来源是否支持和文本抽取,不负责文件权限、业务归属或附件生命周期。DocumentSource中的storageDisk/storagePath/url只是来源描述,starter 第一阶段不会直接读取 Storage 或下载 URL。plain-textprovider 只处理文本类来源;PDF、Office、RTF 和 OpenDocument 通过tikaprovider 接入。
源码机制骨架
| 类型 | 机制职责 |
|---|---|
Document | 静态 Facade,给业务模块提供最短调用入口 |
DocumentManagerProvider | 将 Facade 绑定到 Spring 容器内的 DocumentManager |
DocumentManager | 解析编排入口,负责选择 Provider、合并配置和返回统一结果 |
DefaultDocumentManager | 默认 Manager 实现,按调用选项、全局配置、Provider 配置计算最终限制 |
DocumentProviderCatalog | Provider 只读目录,返回注册状态、启用状态、默认 provider、大小 / 长度 / 超时 / OCR 摘要 |
DocumentProviderDescriptor | Provider 运维描述,不包含业务文件内容、路径凭证或解析结果 |
DocumentProvider | Provider SPI,只负责判断来源是否支持和执行文本抽取 |
DocumentProviderNames | 内置 Provider 名称常量,避免业务侧散落字符串 |
DocumentSource | 文档来源描述,支持 text / bytes / input stream / storage / url |
DocumentExtractOptions | 单次解析选项,用于收紧大小、文本长度、元数据和 OCR 开关 |
DocumentExtractResult | 统一结果,返回文本、元数据、警告和截断状态 |
PlainTextDocumentProvider | 内置纯文本 Provider,承载第一阶段轻量解析能力 |
TikaDocumentProvider | 内置富文档 Provider,承载 PDF、Office、RTF 和 OpenDocument 文本抽取 |
Provider 实现边界
新增 Provider 时只实现 DocumentProvider,并遵守以下边界:
name()返回稳定 provider 名称,内置名称放到DocumentProviderNames。supports(source)只判断来源类型、文件名、MIME 等格式条件,不做业务权限判断。extract(source, options)必须遵守 Manager 传入的最终限制,不能绕过maxFileSizeBytes、maxTextLength等边界。- Provider 返回的 metadata 只放轻量解析信息,不放访问凭证、临时签名 URL 或业务敏感字段。
- Storage 私有文件、URL 下载、业务附件 owner / bizType / scene 校验由调用方或上层业务完成,不在通用 Provider 中硬编码。
- OCR、压缩包递归、超大文件、批量导入等耗时场景应接 AI Task / Queue / Knowledge 流程,不放在同步 Controller 里直接跑。
配置
spring:
open:
document:
enabled: true
default-provider: plain-text
max-file-size: 20MB
max-text-length: 200000
timeout: 30s
ocr-enabled: false
providers:
plain-text:
provider: plain-text
enabled: true
tika:
provider: tika
enabled: true| 配置 | 默认值 | 说明 |
|---|---|---|
spring.open.document.enabled | true | 是否启用文档解析能力;显式设为 false 时关闭 |
spring.open.document.default-provider | plain-text | 默认 provider |
spring.open.document.max-file-size | 20MB | 同步解析最大文件大小 |
spring.open.document.max-text-length | 200000 | 最大抽取文本长度,超过会截断 |
spring.open.document.timeout | 30s | provider 预留超时配置 |
spring.open.document.ocr-enabled | false | OCR 开关预留,默认不引入 OCR 依赖 |
spring.open.document.providers.*.provider | - | provider 使用的实现名称 |
spring.open.document.providers.*.enabled | true | provider 是否启用 |
抽象边界
核心 contract:
| 类型 | 作用 |
|---|---|
Document | Facade,业务侧入口 |
DocumentManager | 选择 provider 并执行解析 |
DocumentProviderCatalog | 输出 provider 运维目录,不读取业务文件 |
DocumentProvider | provider 抽象 |
DocumentSource | 文档来源,支持 text / bytes / input stream / storage / url 描述 |
DocumentExtractOptions | 大小、文本长度、元数据和 OCR 等选项 |
DocumentExtractResult | 抽取结果、元数据、警告和截断标识 |
业务模块只依赖这些项目抽象,不直接依赖第三方解析库。
Plain Text Provider
plain-text 支持:
.txt.md/.markdown.html/.htm.csv.json.xml.yaml/.yml.logtext/*、application/json、application/xml、application/yaml等文本类 MIME
如果文件大小超过 max-file-size,会直接拒绝解析。文本长度超过 max-text-length 时会截断,并在 warnings 中返回 text.truncated。
Tika Provider
tika 支持:
.pdf.doc/.docx.xls/.xlsx.ppt/.pptx.rtf.odt/.ods/.odpapplication/pdf、application/msword、application/vnd.ms-*、application/vnd.openxmlformats-officedocument*、application/vnd.oasis.opendocument*、application/rtf等富文档 MIME
tika 只解析调用方已经授权并传入的 bytes 或 input stream,不主动读取 Storage、URL 或业务文件路径。Provider 会先按 max-file-size 读取受控大小的字节,再把 max-text-length + 1 下推给 Tika,避免同步解析时先构建完整大文本;超过文本长度后同样返回 text.truncated。timeout 会限制同步解析等待时间,超时统一抛出 Document 业务异常,不把底层栈暴露给业务侧。
运维目录
DocumentProviderCatalog 会返回当前应用启动期的 provider 配置、注册状态和本地 smoke 结果:
provider/configKey:稳定 provider 名称和配置键。defaultProvider:是否为默认解析 provider。enabled:配置上是否启用。registered:Spring 容器中是否存在对应 provider Bean。maxFileSizeBytes/maxTextLength/timeoutMillis/ocrEnabled:合并全局配置和 provider 覆盖后的有效限制摘要。providerSmokeResults:使用内存样本执行的本地 contract smoke,内置plain-text/tika会做真实抽取;自定义 Provider 或 OCR 开启时只标记为“需外部验收”,不伪装生产就绪。
该目录只用于 Admin 运维、文档导出或 smoke 检查,不读取业务文件、不展示文件路径凭证、不替业务模块做 Storage 权限校验。
后台管理默认提供只读运维入口:
| 能力 | 入口 |
|---|---|
| 后端 API | GET /api/v1/admin/document/operations |
| 权限 | document:view |
| 菜单 | 任务运维 / 文档解析 |
| 页面 | views/admin/src/views/document/operations/index.vue |
该页面展示默认 provider、Provider 注册 / 启用状态、最大文件大小、最大文本长度、解析超时、OCR 开关、本地 smoke 结果和运维提示。它只用于确认当前实例解析能力,不执行业务文件读取、真实 OCR、Knowledge 索引或业务导入。
与其他模块关系
| 模块 | 关系 |
|---|---|
| Storage | 提供文件来源、权限和私有访问;Document 不重建文件权限模型 |
| 业务附件 | 决定文件归属、场景、owner 和生命周期 |
| Search | 使用抽取文本进入索引,不直接解析文件 |
| Knowledge | 使用抽取文本切片、检索或后续向量化 |
| AI Task / Queue | 承载批量解析、摘要、翻译、向量化等耗时任务 |
后续扩展
同步 Document Provider 不内置真实 OCR、压缩包递归解析、页面级版式还原和超大文件批处理。后续如需接入,优先通过新的 provider、AI Task、Queue 或 Knowledge 流程完成,并为真实 OCR / 批量解析补 Provider 自带 contract 或部署验收清单;本地 smoke 只证明 starter contract 可用,不替代真实厂商样本验收。
验证
./mvnw -pl spring-open-starters/spring-open-starter-document -am test -DskipITs
git diff --check