PDF-OCR文件识别篇(四):百度 OCR 模块文档解析

发布时间:2026/6/26 8:57:14

PDF-OCR文件识别篇(四):百度 OCR 模块文档解析 本章是baiduocr模块的全部。它做两件事先鉴权拿 Access Token再用 Token 调文档解析接口。对外只暴露一个同步parse(bytes, name)把鉴权和轮询全藏在里面。4.1 鉴权用 API Key / Secret 换 Access Token百度文档解析走 OAuth2client_credentials模式参考官方《鉴权认证机制》。配置类BaiduOcrProperties前缀pdf.baidu.ocrData Component ConfigurationProperties(prefix pdf.baidu.ocr) public class BaiduOcrProperties { private String apiKey; // 鉴权 client_id private String secretKey; // 鉴权 client_secret private String tokenUrl https://aip.baidubce.com/oauth/2.0/token; private String docParseTaskUrl .../rest/2.0/brain/online/v2/parser/task; private String docParseQueryUrl .../rest/2.0/brain/online/v2/parser/task/query; private long docParsePollIntervalMs 5000L; // 轮询间隔 private int docParseMaxAttempts 40; // 轮询上限 private long expireBuffer 86400L; // Token 提前刷新安全间隔秒 }所有接口地址、轮询参数都外置成配置切环境不改代码。响应体BaiduTokenResponse用 FastJSON2JSONField做下划线映射一个类同时容纳成功字段与错误字段JSONField(name access_token) private String accessToken; JSONField(name expires_in) private Long expiresIn; // 约 2592000 秒(30天) private String error; // 失败时返回 JSONField(name error_description) private String errorDescription;鉴权服务BaiduOcrTokenServiceImpl接口暴露两个方法getAccessToken()优先读缓存、refreshAccessToken()强制刷新。Override public String getAccessToken() { String cached redisCache.getCacheObject(ACCESS_TOKEN_CACHE_KEY); if (StringUtils.isNotEmpty(cached)) return cached; // 命中缓存直接返回 return refreshAccessToken(); } Override public String refreshAccessToken() { BaiduTokenResponse response requestAccessToken(); String accessToken response.getAccessToken(); // 缓存有效期 百度返回有效期 - 安全间隔避免临界使用到失效 Token long expire response.getExpiresIn() - baiduOcrProperties.getExpireBuffer(); if (expire 0) expire response.getExpiresIn(); redisCache.setCacheObject(ACCESS_TOKEN_CACHE_KEY, accessToken, (int) expire, TimeUnit.SECONDS); return accessToken; }requestAccessToken()用 Hutool POST 表单换 Token并做三层校验MapString,Object params Map.of( grant_type, client_credentials, client_id, apiKey, client_secret, secretKey); String body HttpRequest.post(tokenUrl).form(params).timeout(10000).execute().body(); BaiduTokenResponse response JSONObject.parseObject(body, BaiduTokenResponse.class); if (response null) throw ServiceException(响应为空); if (StringUtils.isNotEmpty(response.getError())) throw ServiceException(鉴权失败: errorDescription); if (无 access_token 或 expiresIn 为空) throw ServiceException(未返回有效 token);设计精华——「提前过期」缓存策略。百度 Token 有效期约 30 天缓存有效期设为30天 - expireBuffer(默认1天)。缓存先于真实 Token 失效下一次取用自然触发刷新永远不会把「马上失效」的 Token 用到接口上。它和下文「失效自动重试」组成双保险。4.2 文档解析异步任务式接口百度「文档解析」是异步任务提交拿 task_id → 轮询查状态 → 成功后下载结果 URL。封装在BaiduDocParseClientImpl。提交任务submitParse文件转 Base64 作为表单字段提交MapString,Object form new HashMap(); form.put(file_data, Base64.encode(fileBytes)); form.put(file_name, fileName); JSONObject json callApi(docParseTaskUrl, form, SUBMIT_TIMEOUT, 提交文档解析任务); checkError(json, 提交文档解析任务); String taskId extractTaskId(json); // 兼容 task_id 在顶层或 result 节点下同步解析parse提交 轮询 下载String taskId submitParse(fileBytes, fileName); for (int i 1; i maxAttempts; i) { Thread.sleep(interval); // 官方建议 5~10s JSONObject result queryResult(taskId); String status lower(str(result, status, task_status)); if (status ∈ {success, succeeded, finished}) { ret.setJsonText(download(str(result, parse_result_url, result_url, json_url))); String mdUrl str(result, markdown_url, md_url); if (mdUrl ! null) ret.setMarkdownText(download(mdUrl)); return ret; // 同时拿到 JSON Markdown 两份 } if (status ∈ {failed, fail, error}) throw ServiceException(任务失败: ...); // pending / running → 继续轮询 } throw ServiceException(文档解析超时);返回的BaiduDocParseResult带jsonText结构化与markdownText人读友好两份taskId、duration备查。4.3 健壮性三件套1Token 失效自动刷新重试。所有请求经callApi包一层命中error_code 110/111Token 过期/无效时刷新 Token 重发一次private JSONObject callApi(String baseUrl, MapString,Object form, int timeout, String action) { JSONObject json doPost(baseUrl, form, timeout, action); Integer code json.getInteger(error_code); if (code ! null (code 110 || code 111)) { baiduOcrTokenService.refreshAccessToken(); // 强刷 json doPost(baseUrl, form, timeout, action); // 重试一次 } return json; }2字段多别名兼容。str(obj, a, b, c)依次取首个非空键吸收百度不同接口版本的字段差异parse_result_url/result_url/json_url…。3分级超时。提交 60s上传大文件慢、查询 30s、下载 60s互不影响。4.4 小结baiduocr把「鉴权 异步任务轮询 容错」全封装在两个 Service 里对上层只给一个parse(bytes, name)。上层第 7 章的ocrParse只管把 PDF 字节丢进去拿回 JSON/Markdown 文本完全不感知 Token 与轮询。关键文件config/BaiduOcrProperties.java— 配置constant/BaiduOcrConstants.java— 缓存 key / grant_typedomain/BaiduTokenResponse.java、domain/BaiduDocParseResult.java— 响应体service/impl/BaiduOcrTokenServiceImpl.java— Access Token 鉴权与缓存service/impl/BaiduDocParseClientImpl.java— 文档解析提交/轮询/下载/容错

相关新闻