首页
学习
活动
专区
圈层
工具
发布

SpringBoot 遇上Apache Tika,数据提取竟如此简单!

平时在公司写业务代码的时候,文件上传是一个再常见不过的功能了。比如 HR 系统里简历上传,OA 里合同上传,或者知识库里各种 PDF、Word 文档一股脑丢上来。问题来了,用户上传之后,这些文档大部分都只是“存起来”,如果要检索里面的内容,或者抽取关键信息,就挺麻烦。

以前我的做法是写一堆针对格式的解析工具,Word 用 POI,PDF 用 PDFBox,Excel 又要换成 JXL 或者 POI,图片里还得套 OCR……代码又臃肿又难维护。后来同事推荐了 Apache Tika,我才发现原来有个工具能“一口气搞定”各种文件解析,省事多了。

那这玩意和 SpringBoot 搭配起来效果怎么样?今天我就聊聊这个话题。

Tika 到底能干啥?

先说白了,Tika 就像是“万能文件解析器”。不管你上传的是 PDF、Word、Excel、PPT,甚至是 HTML、XML、TXT、RTF,它都能帮你提取文本和元数据信息(作者、标题、创建时间之类的)。

举个例子:用户上传了一个 PDF 简历,Tika 可以直接抽出里面的文字,你再丢到 ES(Elasticsearch)里做全文检索,就能支持搜索“Java工程师”“Spring经验”这种关键字了。

换句话说,Tika 的价值就是把复杂的文档解析统一成一个入口,不用再纠结格式差异。

SpringBoot 整合 Tika,其实就几步

SpringBoot 本身是“开箱即用”的风格,所以整合 Tika 也很简单。先引个依赖:

  <groupId>org.apache.tika</groupId>

  <artifactId>tika-core</artifactId>

  <version>2.9.0</version>

  <groupId>org.apache.tika</groupId>

  <artifactId>tika-parsers-standard-package</artifactId>

  <version>2.9.0</version>

上面两个依赖,一个是核心库,一个是常见文件格式解析的“全家桶”。这样基本常见文档都能解析了。

然后写个工具类:

import org.apache.tika.Tika;

import org.apache.tika.metadata.Metadata;

import java.io.InputStream;

public class TikaUtils {

  private static final Tika tika = new Tika();

  public static String extractText(InputStream inputStream) throws Exception {

      return tika.parseToString(inputStream);

  }

  public static Metadata extractMeta(InputStream inputStream) throws Exception {

      Metadata metadata = new Metadata();

      tika.parse(inputStream, metadata);

      return metadata;

  }

}

就这么几行代码,你就能提取文件的内容和元数据了。

写个 SpringBoot Controller 实测一下

假设我们有个上传接口,用户上传 Word 或 PDF,我们解析后返回文档内容。

@RestController

@RequestMapping("/file")

public class FileController {

  @PostMapping("/upload")

  public String uploadFile(@RequestParam("file") MultipartFile file) {

      try (InputStream inputStream = file.getInputStream()) {

          String content = TikaUtils.extractText(inputStream);

          return content.length() > 200

              ? content.substring(0, 200) + "..."

              : content;

      } catch (Exception e) {

          return "解析失败:" + e.getMessage();

      }

  }

}

这个接口会返回文档前 200 个字符的内容。你完全可以把它扩展成全文检索、存储数据库、或者喂给 NLP 模型做实体识别。

遇到大文件怎么办?

这里要提醒一句,Tika 解析大文件的时候性能不是特别快,尤其是几百 MB 的 PDF,直接 parseToString 会很吃内存。

我的经验是:

流式处理—— 用BodyContentHandler限制输出大小,避免一次性吃光内存。

异步任务—— 大文件解析最好丢到消息队列(比如 Kafka 或 RabbitMQ)里慢慢处理,不要在请求线程里直接做。

举个改造例子:

import org.apache.tika.sax.BodyContentHandler;

import org.xml.sax.ContentHandler;

try (InputStream inputStream = file.getInputStream()) {

  ContentHandler handler = new BodyContentHandler(10 * 1024 * 1024); // 最大10MB文本

  Metadata metadata = new Metadata();

  new AutoDetectParser().parse(inputStream, handler, metadata);

  String content = handler.toString();

}

这样就能避免一次性加载超大文本导致 OOM。

元数据的妙用

除了文本,Tika 抽取的元数据也很有意思。比如上传的 PPT,它能告诉你创建时间、最后修改人、标题;上传图片,它能解析 EXIF 信息,比如拍摄时间、相机型号。这些信息在业务里经常能用上。

我之前做过一个小功能:用户上传的合同 PDF,Tika 自动抽取创建时间和作者信息,用来校验是否和用户填写的表单一致,避免“上传错文件”的情况。

实战:全文检索一把梭

如果你只停留在“解析然后展示”,其实还没发挥出 Tika 的威力。最常见的场景还是全文检索

一个简单的方案:

文件上传 SpringBoot Controller

用 Tika 抽取文本

把文本和文件信息存进 Elasticsearch

用户搜索时直接查 ES

代码片段示意:

Map<String, Object> doc = new HashMap<>();

doc.put("filename", file.getOriginalFilename());

doc.put("content", TikaUtils.extractText(file.getInputStream()));

doc.put("uploadTime", System.currentTimeMillis());

IndexRequest request = new IndexRequest("documents")

      .id(UUID.randomUUID().toString())

      .source(doc);

client.index(request, RequestOptions.DEFAULT);

这样,用户搜“合同编号”“发票金额”,就能命中 PDF 或 Word 里的文字了,体验直接拉满。

和 SpringBoot 的一些坑

虽然整合很简单,但我踩过几个坑:

编码问题:有些旧版 Word 文档解析出来会乱码,需要手动转码。

解析时间过长:某些复杂 PDF 带有图片嵌入,解析时间会非常久。解决方法是加超时控制。

依赖冲突:Tika 的依赖挺多,和 SpringBoot 项目里其他依赖容易打架,尤其是日志框架,要注意排除冲突包。

SpringBoot + Apache Tika,组合起来就是一套“文件内容挖掘工具箱”。你不用再为各种格式写一堆解析逻辑,直接交给 Tika,SpringBoot 负责封装接口和业务逻辑。

这玩意最适合用在:

简历管理系统(快速搜索候选人技能)

知识库(支持全文检索 PDF/Word)

合同档案(抽取元数据做校验)

搜索引擎(文本提取后丢到 ES)

可以说,它是文档处理的“瑞士军刀”。

兄弟们,你们要是项目里有文件上传的需求,真的可以考虑整合下 Tika,几行代码就能见效。我第一次上线时,老板还以为我写了什么黑科技,其实就是用了现成的库罢了。

写到这里差不多了,等下还要去开会,代码我就不贴更多了,有兴趣的自己试试,绝对比你一个个写解析器省事。

  • 发表于:
  • 原文链接https://page.om.qq.com/page/OGN7weArUddwGnbjwV-3GuwA0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。
领券