跳到内容

文档解析

受众:开发者 摘要: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。

快速开始

按需引入:

xml
<dependency>
    <groupId>com.springopen</groupId>
    <artifactId>spring-open-starter-document</artifactId>
</dependency>

启用:

yaml
spring:
  open:
    document:
      enabled: true
      default-provider: plain-text

Facade 使用:

java
DocumentExtractResult result = Document.extract(
        DocumentSource.text("readme.md", "# Hello"));

String text = result.getText();

也可以显式传入选项:

java
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-text provider 只处理文本类来源;PDF、Office、RTF 和 OpenDocument 通过 tika provider 接入。

源码机制骨架

类型机制职责
Document静态 Facade,给业务模块提供最短调用入口
DocumentManagerProvider将 Facade 绑定到 Spring 容器内的 DocumentManager
DocumentManager解析编排入口,负责选择 Provider、合并配置和返回统一结果
DefaultDocumentManager默认 Manager 实现,按调用选项、全局配置、Provider 配置计算最终限制
DocumentProviderCatalogProvider 只读目录,返回注册状态、启用状态、默认 provider、大小 / 长度 / 超时 / OCR 摘要
DocumentProviderDescriptorProvider 运维描述,不包含业务文件内容、路径凭证或解析结果
DocumentProviderProvider 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 传入的最终限制,不能绕过 maxFileSizeBytesmaxTextLength 等边界。
  • Provider 返回的 metadata 只放轻量解析信息,不放访问凭证、临时签名 URL 或业务敏感字段。
  • Storage 私有文件、URL 下载、业务附件 owner / bizType / scene 校验由调用方或上层业务完成,不在通用 Provider 中硬编码。
  • OCR、压缩包递归、超大文件、批量导入等耗时场景应接 AI Task / Queue / Knowledge 流程,不放在同步 Controller 里直接跑。

配置

yaml
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.enabledtrue是否启用文档解析能力;显式设为 false 时关闭
spring.open.document.default-providerplain-text默认 provider
spring.open.document.max-file-size20MB同步解析最大文件大小
spring.open.document.max-text-length200000最大抽取文本长度,超过会截断
spring.open.document.timeout30sprovider 预留超时配置
spring.open.document.ocr-enabledfalseOCR 开关预留,默认不引入 OCR 依赖
spring.open.document.providers.*.provider-provider 使用的实现名称
spring.open.document.providers.*.enabledtrueprovider 是否启用

抽象边界

核心 contract:

类型作用
DocumentFacade,业务侧入口
DocumentManager选择 provider 并执行解析
DocumentProviderCatalog输出 provider 运维目录,不读取业务文件
DocumentProviderprovider 抽象
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
  • .log
  • text/*application/jsonapplication/xmlapplication/yaml 等文本类 MIME

如果文件大小超过 max-file-size,会直接拒绝解析。文本长度超过 max-text-length 时会截断,并在 warnings 中返回 text.truncated

Tika Provider

tika 支持:

  • .pdf
  • .doc / .docx
  • .xls / .xlsx
  • .ppt / .pptx
  • .rtf
  • .odt / .ods / .odp
  • application/pdfapplication/mswordapplication/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.truncatedtimeout 会限制同步解析等待时间,超时统一抛出 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 权限校验。

后台管理默认提供只读运维入口:

能力入口
后端 APIGET /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 可用,不替代真实厂商样本验收。

验证

bash
./mvnw -pl spring-open-starters/spring-open-starter-document -am test -DskipITs
git diff --check

Released under the Apache License 2.0.