深入解析 Docling Java SDK 集成:Source 与 Target 的实战应用
前言:Docling 的两种调用方式
Docling 文档解析引擎提供了两种调用方式:
方式一:HTTP 原生请求
部署 Docling 服务后,可以直接使用 HTTP REST API 进行调用:
bash
# 示例:使用 curl 上传文件进行解析
curl -X POST http://localhost:5001/convert \
-H "Content-Type: multipart/form-data" \
-F "file=@document.pdf" \
-F "output_format=json"
这种方式适合:
- 非 Java 项目集成
- 跨语言调用
- 简单验证和测试
方式二:Java SDK(推荐方案)
对于 Java 项目,Docling 官方提供了专门的 Java SDK,封装了 HTTP 请求细节:
java
// 使用 SDK 进行文档解析
ConvertDocumentRequest request = ConvertDocumentRequest.builder()
.source(FileSource.builder()
.filename("document.pdf")
.base64String(base64)
.build())
.target(InBodyTarget.builder().build())
.build();
ConvertDocumentResponse response = doclingClient.convert(request);
Java SDK 的核心优势:
- 生态集成:无缝对接 Spring Boot、Micronaut 等主流框架
- 类型安全:Builder 模式提供编译期检查,降低配置错误
- 异常封装:统一的异常体系,便于业务层处理
- 依赖注入:支持 Spring Bean 管理,符合现代 Java 开发范式
为什么需要深入理解 SDK 设计?
官方文档的现状是:只展示了最基础的用法示例,比如如何创建一个 ConvertDocumentRequest 并调用 convert() 方法。但对于实际项目开发需要的关键信息,文档存在明显的缺失:
缺失的 API 说明:
FileSource有几种构建方式?每种方式的内部实现机制是什么?UrlSource如何使用?URL 需要满足什么条件(公网可访问?需要鉴权?)InBodyTarget是唯一的 Target 类型吗?未来会有扩展吗?ConvertDocumentResponse的结构是什么?如何提取解析结果?
缺失的方法细节:
FileSource.fromInputStream()内部如何处理流?会自动转 Base64 吗?- Builder 模式的必填字段和可选字段有哪些?
- 异常体系是什么样的?哪些异常需要业务层处理?
这些信息在官方文档中要么没提及,要么一笔带过,开发者只能通过阅读源码或反复调试来摸索。
第一个坑:Source 类型的选择
文档只列出了 FileSource.fromFile()、FileSource.fromInputStream() 等方法,但没有说明什么场景用什么。新手往往会直接用 fromFile(),直到遇到 100MB 的 PDF 导致内存溢出才发现问题。实际上:
- 小文件(< 10MB):Base64 方案简单直接
- 上传流:
fromInputStream()更自然 - 大文件(> 100MB):应该用
UrlSource,让 Docling 服务端直接拉取
这些边界文档没写,只能靠踩坑学习。
第二个坑:Target 的概念混淆
很多开发者看到 InBodyTarget 就理解为"上传方式",实际上它控制的是"响应返回方式"。这个误解会导致后续设计出错误的架构------比如试图通过 Target 来控制文件传输,或者不理解为什么大文件解析会阻塞 HTTP 连接。
第三个坑:文档没有提到的性能边界
Base64 编码会导致 ~33% 的数据膨胀,对于大文件来说这是显著的内存压力。但文档没有给出明确的大小阈值,开发者只能自己摸索什么时候切换到 UrlSource。
本文的价值在于:帮你避开这些坑,建立正确的设计思维,而不是等你踩坑后再复盘。
认知误区:一个常见的概念陷阱
一句话模型 :
Source = 文件从哪里来(输入),Target = 结果怎么返回(输出)
在集成 Docling Java SDK 时,很多开发者(包括笔者)都会陷入一个概念陷阱:
java
ConvertDocumentRequest request = ConvertDocumentRequest.builder()
.source(FileSource.builder()
.filename(filename)
.base64String(base64)
.build())
.target(InBodyTarget.builder().build())
.build();
看到这段代码,第一反应往往是:
"FileSource 是描述文件,InBodyTarget 是实际传输方式"
或者更模糊的理解:
"InBodyTarget 决定了文件怎么传过去"
这些理解都是错误的,而且这种错误理解会导致后续架构设计出现严重偏差。
Source 和 Target 的基本理解
Docling SDK 的设计遵循了职责分离原则,将文档处理请求拆解为三个独立维度:
text
ConvertDocumentRequest
├── source ← 输入数据(文件从哪里来)
├── options ← 解析配置(如何处理)
└── target ← 输出结果(结果怎么回)
这个设计揭示了 Docling 的核心理念:
text
Source 负责:数据供给(怎么进来)
Target 负责:结果交付(怎么出去)
Options 负责:处理策略(中间过程)
Source 的四种供给方式
Source 决定了文件如何进入 Docling 处理流程。SDK 提供了四种供给方式,从手动编码到自动化处理,呈现出明显的递进关系。
1. Base64 手动编码:最基础的方式
完整调用示例:
java
import java.net.URI;
import java.util.Base64;
import ai.docling.serve.api.DoclingServeApi;
import ai.docling.serve.api.convert.request.ConvertDocumentRequest;
import ai.docling.serve.api.convert.request.options.ConvertDocumentOptions;
import ai.docling.serve.api.convert.request.options.OutputFormat;
import ai.docling.serve.api.convert.request.source.FileSource;
import ai.docling.serve.api.convert.request.target.InBodyTarget;
import ai.docling.serve.api.convert.response.ConvertDocumentResponse;
// 创建 Docling API 客户端
DoclingServeApi api = DoclingServeApi.builder()
.baseUrl("http://localhost:8000")
.logRequests()
.logResponses()
.prettyPrint()
.build();
// 手动将文件读取并编码为 Base64(在内存中处理)
byte[] fileBytes = Files.readAllBytes(Paths.get("document.pdf"));
String base64 = Base64.getEncoder().encodeToString(fileBytes);
// 构建 Request,手动传入 Base64 字符串
ConvertDocumentRequest request = ConvertDocumentRequest.builder()
.source(FileSource.builder()
.filename("document.pdf")
.base64String(base64)
.build())
.options(ConvertDocumentOptions.builder()
.toFormat(OutputFormat.MARKDOWN)
.build())
.target(InBodyTarget.builder().build())
.build();
// 调用并获取结果
ConvertDocumentResponse response = api.convertSource(request);
System.out.println(response.getDocument().getMarkdownContent());
这种方式是在客户端内存中手动读取文件、编码为 Base64,然后发送给 Docling 服务。文件数据完全在客户端处理。
优点:
- 代码简单直观,易于理解
- SDK 直接支持,无需额外处理
- 适合已有 Base64 数据的场景(如前端上传的 Base64 字符串)
缺点:
- Base64 编码导致 ~33% 数据膨胀,增加内存压力
- 大文件编码耗时长,阻塞上传流程
- 编码/解码有额外 CPU 开销
适用边界:小文件(< 10MB),或已有 Base64 数据的场景。
Base64 编码对大文件的具体问题
数据膨胀问题:
Base64 编码将每 3 个字节编码为 4 个字符,导致数据量增加约 33%。对于大文件,这意味着:
原始文件大小:100 MB
Base64 编码后:133 MB
内存峰值:100 MB(原始) + 133 MB(编码) + 额外开销
内存占用问题:
在 Java 环境中,Base64 编码过程会导致显著的内存压力:
- 原始文件加载 :
Files.readAllBytes()将整个文件加载到内存 - Base64 字符串创建:编码后的字符串再次占用内存
- HTTP 请求构建:请求对象包含完整的 Base64 字符串
对于一个 100 MB 的文件,实际内存占用可能超过 300 MB。
GC 压力问题:
大字符串对象会进入 JVM 的老年代(Old Generation),导致:
- Full GC 频繁触发
- 应用响应时间变长
- 可能导致 OutOfMemoryError
网络传输问题:
即使服务器带宽充足,Base64 编码仍然会导致:
- 上传时间增加 33%
- Docling 服务端需要解码 Base64,额外消耗 CPU
- 整体处理时间延长
实战建议:
| 文件大小 | 推荐方式 | 原因 |
|---|---|---|
| < 10MB | Base64 | 内存压力可控,实现简单 |
| 10-50MB | InputStream | 流式处理,减少内存峰值 |
| > 50MB | HTTP URL | 零内存压力,生产级方案 |
2. InputStream:更优雅的流式供给
完整调用示例:
java
import java.io.InputStream;
import java.net.URI;
import ai.docling.serve.api.DoclingServeApi;
import ai.docling.serve.api.convert.request.ConvertDocumentRequest;
import ai.docling.serve.api.convert.request.options.ConvertDocumentOptions;
import ai.docling.serve.api.convert.request.options.OutputFormat;
import ai.docling.serve.api.convert.request.source.FileSource;
import ai.docling.serve.api.convert.request.target.InBodyTarget;
import ai.docling.serve.api.convert.response.ConvertDocumentResponse;
// 创建 Docling API 客户端
DoclingServeApi api = DoclingServeApi.builder()
.baseUrl("http://localhost:8000")
.build();
// 从上传流或文件流获取 InputStream
InputStream inputStream = new FileInputStream("document.pdf");
// 构建 Request,SDK 自动处理流数据
ConvertDocumentRequest request = ConvertDocumentRequest.builder()
.source(FileSource.fromInputStream(inputStream, "document.pdf"))
.options(ConvertDocumentOptions.builder()
.toFormat(OutputFormat.MARKDOWN)
.build())
.target(InBodyTarget.builder().build())
.build();
// 调用并获取结果
ConvertDocumentResponse response = api.convertSource(request);
System.out.println(response.getDocument().getMarkdownContent());
// 注意:记得关闭流
inputStream.close();
这种方式让 SDK 自动处理流数据,开发者只需传入 InputStream。SDK 内部会将流转换为 Base64,但开发者无需手动处理编码细节。
优点:
- 流式读取,内存占用可控
- SDK 内部自动转 Base64,开发者无需手动编码
- 更符合 Java IO 编程习惯
- 适合网络上传流、管道式处理场景
缺点:
- SDK 内部仍然会转 Base64,大文件仍有内存压力
- 需要管理流的关闭,增加代码复杂度
- InputStream 一旦读取完毕无法重用
适用边界:中等文件(10MB - 100MB),或网络上传流场景。
3. File 本地文件:开发调试的便捷方案
完整调用示例:
java
import java.io.File;
import java.net.URI;
import ai.docling.serve.api.DoclingServeApi;
import ai.docling.serve.api.convert.request.ConvertDocumentRequest;
import ai.docling.serve.api.convert.request.options.ConvertDocumentOptions;
import ai.docling.serve.api.convert.request.options.OutputFormat;
import ai.docling.serve.api.convert.request.source.FileSource;
import ai.docling.serve.api.convert.request.target.InBodyTarget;
import ai.docling.serve.api.convert.response.ConvertDocumentResponse;
// 创建 Docling API 客户端
DoclingServeApi api = DoclingServeApi.builder()
.baseUrl("http://localhost:8000")
.build();
// 直接传入本地 File 对象
File file = new File("document.pdf");
// 构建 Request,一行代码完成文件供给
ConvertDocumentRequest request = ConvertDocumentRequest.builder()
.source(FileSource.fromFile(file))
.options(ConvertDocumentOptions.builder()
.toFormat(OutputFormat.MARKDOWN)
.build())
.target(InBodyTarget.builder().build())
.build();
// 调用并获取结果
ConvertDocumentResponse response = api.convertSource(request);
System.out.println(response.getDocument().getMarkdownContent());
这种方式是本地开发最便捷的选择,SDK 自动处理文件读取和 Base64 编码,开发者只需一行代码。
优点:
- 一行代码完成文件供给,极低复杂度
- 本地批处理脚本、文件扫描任务最适用
- SDK 自动处理文件读取和编码
缺点:
- SDK 内部仍然转 Base64,不适合大文件
- 仅适用于本地文件系统,生产环境不推荐
- 文件路径依赖本地环境,部署时需调整
适用边界:本地开发调试、批处理脚本,不推荐生产环境。
4. URL 远程供给:推荐的主流方案
完整调用示例:
java
import java.net.URI;
import ai.docling.serve.api.DoclingServeApi;
import ai.docling.serve.api.convert.request.ConvertDocumentRequest;
import ai.docling.serve.api.convert.request.options.ConvertDocumentOptions;
import ai.docling.serve.api.convert.request.options.OutputFormat;
import ai.docling.serve.api.convert.request.source.HttpSource;
import ai.docling.serve.api.convert.request.target.InBodyTarget;
import ai.docling.serve.api.convert.response.ConvertDocumentResponse;
// 创建 Docling API 客户端
DoclingServeApi api = DoclingServeApi.builder()
.baseUrl("http://localhost:8000")
.logRequests()
.logResponses()
.prettyPrint()
.build();
// 构建 Request,传入文件的 URL(推荐方式)
ConvertDocumentRequest request = ConvertDocumentRequest.builder()
.source(HttpSource.builder()
.url(URI.create("https://arxiv.org/pdf/2408.09869"))
.build())
.options(ConvertDocumentOptions.builder()
.toFormat(OutputFormat.MARKDOWN)
.includeImages(true)
.build())
.target(InBodyTarget.builder().build())
.build();
// 调用并获取结果(Docling 服务端直接从 URL 拉取文件)
ConvertDocumentResponse response = api.convertSource(request);
System.out.println(response.getDocument().getMarkdownContent());
这是生产环境推荐的主流方案。Docling 服务端直接从 URL 拉取文件,客户端零内存压力,避开了 Base64 编码的所有问题。
优点:
- 客户端零内存压力,文件由 Docling 服务端拉取
- 无需 Base64 编码,避免数据膨胀和内存占用问题
- 天然支持云存储(OSS、S3、CDN)
- 不受客户端带宽限制
- 处理速度更快,整体延迟更低
缺点:
- URL 必须公网可访问,或需配置鉴权
- 增加 URL 管理复杂度(生成、鉴权、过期时间)
- 依赖云存储基础设施
适用边界 :生产环境推荐方案,特别是大文件(> 50MB)、云存储集成的场景。
Source 的官方支持模式
根据官方文档,SDK 实际支持两种核心 Source 类型:
HttpSource:从 URL 获取内容
java
HttpSource.builder()
.url(URI.create("https://example.com/document.pdf"))
.build()
可选配置:自定义 HTTP Headers
FileSource:将内容以 Base64 编码嵌入
java
FileSource.builder()
.filename("document.pdf")
.base64String(base64) // Base64 编码内容
.build()
FileSource.fromFile(file) // SDK 自动读取并转 Base64
FileSource.fromInputStream(is) // SDK 自动处理流并转 Base64
核心特性:FileSource 会将文件内容以 Base64 编码嵌入到请求中。
SDK 内部的 Base64 转换机制详解
官方文档明确指出:FileSource 将内容以 Base64 编码嵌入到文件名中。这意味着:
三种 Base64 处理方式对比:
- 手动 Base64 方式:
java
byte[] fileBytes = Files.readAllBytes(Paths.get("document.pdf"));
String base64 = Base64.getEncoder().encodeToString(fileBytes);
FileSource.builder()
.filename("document.pdf")
.base64String(base64)
.build()
开发者显式控制:文件读取 → Base64编码 → 传入SDK
- SDK 自动转换(File):
java
FileSource.fromFile(file)
SDK 内部处理:File读取 → Base64编码 → 嵌入请求
- SDK 自动转换(InputStream):
java
FileSource.fromInputStream(inputStream, "document.pdf")
SDK 内部处理:InputStream读取 → Base64编码 → 嵌入请求
关键区别:
- 手动方式:开发者控制编码时机和内存占用,适合已有 Base64 数据
- SDK 自动转换:开发者无需关心编码细节,但内存占用仍存在
官方文档说明:FileSource 会将内容以 Base64 编码嵌入到请求中,这是 SDK 的内部实现机制。
大文件的核心问题:无论手动还是自动,Base64 编码都在客户端内存中进行,大文件会导致内存压力。HttpSource 是唯一避免客户端内存压力的方案(Docling 服务端直接从 URL 拉取)。
Target 的三种结果返回方式
Target 决定了解析结果如何返回给客户端。根据官方文档,SDK 支持三种 Target 类型:
1. InBodyTarget:直接返回模式(默认用例)
java
Target target = InBodyTarget.builder().build();
解析结果直接封装在 HTTP Response Body 中返回,这是默认的方式。
特点:
- 同步阻塞:请求期间客户端等待
- 即时获取:无需二次请求
- 内存敏感:大文档结果占用客户端内存
适用场景:小文档、即时处理、同步调用场景。
2. PutTarget:服务端上传模式
java
Target target = PutTarget.builder()
.url(URI.create("https://your-storage.com/upload"))
.build();
Docling 服务端通过 HTTP PUT 将解析结果上传到指定的 URI,客户端不直接接收文档内容,而是接收上传结果。 解析结果 → Docling 服务端通过 HTTP PUT 上传到指定 URI → 返回上传结果
yaml
特点:
- 服务端上传:Docling 主动将结果上传到指定存储
- 客户端接收上传结果,不直接接收文档内容
- 适合对接云存储(OSS、S3)的场景
适用场景:需要将解析结果直接存储到云存储的场景。
---
### 3. ZipTarget:压缩返回模式
```java
Target target = ZipTarget.builder().build();
解析结果压缩为 ZIP 文件后,通过 HTTP Response Body 返回。
特点:
- 结果压缩:减少传输数据量
- 适合包含图片、多文档的解析结果
- 客户端接收 ZIP 文件,需要解压处理
适用场景:包含大量图片的文档解析、批量文档处理结果。
Target 的选择策略
InBodyTarget 是默认方式。
选择建议:
- InBodyTarget:默认选择,适合大部分场景
- PutTarget:需要直接存储到云存储时选择
- ZipTarget:解析结果包含大量图片或需要批量处理时选择
组合模式矩阵:Source × Target
基于 Source 和 Target 的独立维度,可组合出多种实战方案:
组合 1:Base64 + InBodyTarget(快速集成)
java
ConvertDocumentRequest.builder()
.source(FileSource.builder()
.filename("test.pdf")
.base64String(base64)
.build())
.target(InBodyTarget.builder().build())
.build();
适用场景:原型验证、单元测试、小文件处理。
组合 2:InputStream + InBodyTarget(流式上传)
java
ConvertDocumentRequest.builder()
.source(FileSource.fromInputStream(inputStream, "upload.pdf"))
.target(InBodyTarget.builder().build())
.build();
适用场景:Web 上传接口、管道式处理链。
组合 3:URL + InBodyTarget(大文件推荐)
java
ConvertDocumentRequest.builder()
.source(UrlSource.builder()
.url("https://oss.example.com/large-doc.pdf")
.build())
.target(InBodyTarget.builder().build())
.build();
适用场景:生产级大文件处理、云存储集成。
组合 4:File + InBodyTarget(本地批处理)
java
ConvertDocumentRequest.builder()
.source(FileSource.fromFile(new File("/data/batch/doc.pdf")))
.target(InBodyTarget.builder().build())
.build();
适用场景:后台脚本、批量索引任务。
Options 的解析配置
ConvertDocumentOptions 控制文档解析的策略和行为,是 Source/Target/Options 三维度中"中间过程"的配置层。
根据官方文档,Options 支持丰富的配置项:
核心配置项
输出格式控制:
java
ConvertDocumentOptions.builder()
.toFormat(OutputFormat.MARKDOWN) // 输出为 Markdown
.toFormat(OutputFormat.HTML) // 输出为 HTML
.toFormat(OutputFormat.JSON) // 输出为 JSON 结构
.build()
OCR 配置:
java
ConvertDocumentOptions.builder()
.doOcr(true) // 开启 OCR
.forceOcr(true) // 强制 OCR(即使有文本层)
.ocrEngine("tesseract") // OCR引擎选择
.ocrLang("en") // OCR语言设置
.build()
PDF 处理配置:
java
ConvertDocumentOptions.builder()
.pdfBackend("pypdfium") // PDF后端选择
.build()
表格识别配置:
java
ConvertDocumentOptions.builder()
.doTableStructure(true) // 开启表格识别
.tableMode("accurate") // 表格识别模式
.tableCellMatching(true) // 表格单元格匹配
.build()
处理范围控制:
java
ConvertDocumentOptions.builder()
.pipeline("standard") // 管道选择
.pageRange("1-10") // 页面范围限制
.documentTimeout(300000) // 文档处理超时(毫秒)
.abortOnError(false) // 错误时是否中止
.build()
增强功能配置:
java
ConvertDocumentOptions.builder()
.includeImages(true) // 包含图片
.imageScale(2.0) // 图片缩放比例
.enableCodeDetection(true) // 代码检测
.enableFormulaDetection(true) // 公式检测
.build()
完整配置示例
java
ConvertDocumentRequest request = ConvertDocumentRequest.builder()
.source(HttpSource.builder()
.url(URI.create("https://arxiv.org/pdf/2408.09869"))
.build())
.options(ConvertDocumentOptions.builder()
.toFormat(OutputFormat.MARKDOWN)
.includeImages(true)
.doOcr(true)
.ocrLang("en")
.doTableStructure(true)
.pageRange("1-5")
.documentTimeout(60000)
.build())
.target(InBodyTarget.builder().build())
.build();
项目自定义 Options vs 官方 Options
很多项目会自定义 Options DTO(如本项目定义的 DoclingOptions),通常只封装核心配置项:
java
@Data
@Builder
public class DoclingOptions {
@Builder.Default
private boolean ocr = true;
@Builder.Default
private boolean tables = true;
@Builder.Default
private boolean includeImages = true;
}
对比分析:
- 项目自定义:简化配置,聚焦核心需求,易于维护
- 官方 SDK:配置全面,适合复杂场景,但配置项繁多
建议:
- 项目初期:使用自定义 Options,快速验证功能
- 生产环境:根据业务需求,逐步引入官方 SDK 的高级配置
常见误区纠正:为什么"上传方式 ≠ Target"
错误认知链
text
看到代码:.target(InBodyTarget.builder().build())
产生误解:这是控制上传方式的配置
导致问题:混淆输入和输出的职责边界
正确认知链
text
看到代码:.target(InBodyTarget.builder().build())
正确解读:这是控制响应返回方式的配置
关联理解:上传方式在 Source 中决定(如 base64String 字段)
为什么会产生混淆?
因为 SDK 提供了"隐式转换":
java
FileSource.fromFile(file) // SDK 自动:File → Base64
开发者看到一行代码就完成了文件到传输数据的转换,容易产生错觉:
"Target 控制了文件如何传输"
但实际上:
text
文件读取 → FileSource 内部处理
Base64编码 → FileSource 内部处理
HTTP传输 → SDK 底层实现
结果返回 → Target 控制
职责边界非常清晰:
| 阶段 | 负责组件 | 开发者可见度 |
|---|---|---|
| 文件读取 | FileSource | 可选 API |
| 数据编码 | FileSource | 隐式执行 |
| HTTP请求 | SDK底层 | 不可见 |
| 响应解析 | Target | 可配置 |
系统设计层面的思考:从 API 到架构
当你正确理解 Source/Target 后,下一步的设计重点不再是"怎么写代码",而是:
1. 任务控制问题
text
当前痛点:
请求同步阻塞 → 处理中无法取消
用户上传后 → 必须等待完成才能删除文件
架构解法:
- 引入任务队列(Task Queue)
- 支持任务取消 API
- 异步处理 + 通知回调
2. 大文件策略问题
text
当前痛点:
Base64 方案 → 大文件内存爆炸
同步等待 → 超时风险
架构解法:
-
自动 Source 切换策略:
textfile.size < 10MB → Base64Source file.size < 100MB → InputStreamSource file.size > 100MB → UrlSource(需 OSS 支持) -
引入任务 ID + 分片上传
3. 并发安全问题
text
当前痛点:
多用户同时上传 → 文件生命周期混乱
处理中删除 → 资源竞争
架构解法:
-
文件状态机管理:
textUPLOADED → PROCESSING → COMPLETED → CLEANED -
分布式锁(Redisson)保护处理状态
-
任务取消时清理临时资源
最佳实践总结
开发阶段建议
- 原型开发 :使用
Base64 + InBodyTarget,快速验证逻辑 - 集成测试 :使用
InputStream + InBodyTarget,模拟真实上传流 - 性能测试 :使用
UrlSource + InBodyTarget,验证大文件处理能力
生产环境建议
-
小文件场景(< 10MB):
javaFileSource.fromInputStream(uploadStream, filename) -
大文件场景(> 100MB):
javaUrlSource.builder().url(ossUrl).build() -
批处理场景:
javaFileSource.fromFile(localFile)
架构演进建议
-
短期:
- 封装 Source 选择策略
- 添加文件大小检查拦截器
-
中期:
- 引入任务队列
- 支持异步处理
-
长期:
- 实现可取消任务系统
- 完善文件生命周期管理
终极记忆模型
Source 解决"我给你什么",Target 解决"你怎么还我"
当你下次看到这段代码时:
java
.source(FileSource.builder().base64String(base64).build())
.target(InBodyTarget.builder().build())
脑海中应该立刻浮现:
text
输入:我用 Base64 给你文件
输出:你直接把解析结果还给我
中间:Docling 按照 options 配置处理
而不是混淆为:
text
错误理解1:Target 控制上传方式
错误理解2:InBodyTarget 决定文件怎么传
结语
Docling 的 Source/Target 设计职责清晰、维度独立、组合灵活。
理解这一设计,不仅让你写出正确的集成代码,更重要的是:
- 为后续架构设计打下正确基础
- 避免"错误认知导致错误架构"的陷阱
- 具备从 API 层面思考系统设计的能力