最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot3使用Apache Tika實現(xiàn)多格式文件內(nèi)容提取

 更新時間:2026年03月30日 09:31:18   作者:碼路星河  
做后端開發(fā)久了,難免碰到這類剛需:用戶上傳Word、PDF、Excel、Txt各種文檔,后臺得自動扒出文本做內(nèi)容審核、全文檢索或者數(shù)據(jù)庫歸檔,所以本文使用 Apache Tika 搞定全格式解析,需要的朋友可以參考下

做后端開發(fā)久了,難免碰到這類剛需:用戶上傳Word、PDF、Excel、Txt各種文檔,后臺得自動扒出文本做內(nèi)容審核、全文檢索或者數(shù)據(jù)庫歸檔。要是挨個用POI、PDFBox適配格式,代碼寫得又碎又亂,后期維護、擴展全是坑。

本文使用 Apache Tika 搞定全格式解析,不用管底層解析差異,支持文件類型識別、元數(shù)據(jù)提取、格式校驗這幾個開發(fā)必用的高頻場景,完全貼合真實業(yè)務(wù)。

一、前期準(zhǔn)備:項目環(huán)境與核心依賴

先說明環(huán)境版本:

  • JDK版本:17+
  • SpringBoot版本:3.2.5
  • Tika:3.2.3

在pom.xml文件引入相關(guān)依賴:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <!-- Maven模型版本,固定4.0.0適配SpringBoot3 -->
    <modelVersion>4.0.0</modelVersion>
    <!-- SpringBoot3父依賴,統(tǒng)一版本管理,避免依賴沖突 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.5</version>
        <relativePath/>
    </parent>
    <!-- 項目基礎(chǔ)信息,可根據(jù)實際業(yè)務(wù)修改 -->
    <groupId>com.example</groupId>
    <artifactId>springboot3-tika-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot3-tika-demo</name>
    <description>SpringBoot3集成Apache Tika文件解析實戰(zhàn)</description>
    <!-- 全局版本屬性,統(tǒng)一管理依賴版本,方便后續(xù)升級 -->
    <properties>
        <java.version>17</java.version>
        <tika.version>3.2.3</tika.version>
    </properties>
    <dependencies>
        <!-- SpringBoot Web核心依賴,提供HTTP接口、MVC等能力 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- Tika核心依賴,提供基礎(chǔ)文件解析API -->
        <dependency>
            <groupId>org.apache.tika</groupId>
            <artifactId>tika-core</artifactId>
            <version>${tika.version}</version>
        </dependency>
        <!-- Tika標(biāo)準(zhǔn)解析器池,覆蓋Office/PDF/TXT/Excel等主流辦公格式 -->
        <dependency>
            <groupId>org.apache.tika</groupId>
            <artifactId>tika-parsers-standard-pooled</artifactId>
            <version>${tika.version}</version>
            <type>pom</type>
        </dependency>
        <!-- Apache通用工具包,簡化字符串、集合、IO操作 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.20.0</version>
        </dependency>
        <!-- Lombok注解工具,省略Getter/Setter/構(gòu)造器,簡化代碼 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- FastJSON2,高性能JSON序列化/反序列化,適配接口返回 -->
        <dependency>
            <groupId>com.alibaba.fastjson2</groupId>
            <artifactId>fastjson2</artifactId>
            <version>2.0.32</version>
        </dependency>
        <!-- 單元測試依賴,本地調(diào)試、接口測試使用 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <!-- SpringBoot打包插件,打包可執(zhí)行JAR -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <!-- 打包時排除lombok,減小jar包體積 -->
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

二、實戰(zhàn)集成:三步寫完核心代碼

1. 單例配置:避免重復(fù)創(chuàng)建實例

AutoDetectParser自動解析器是線程安全的,沒必要每次解析都新建實例,交給Spring托管單例最劃算,既能節(jié)省內(nèi)存開銷,后續(xù)自定義解析規(guī)則、擴展配置也更方便。

import org.apache.tika.parser.AutoDetectParser;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
 * Tika解析器配置類
 * 作用:將AutoDetectParser交給Spring管理單例,避免重復(fù)創(chuàng)建消耗資源
 */
@Configuration
public class FileDetectParserConfig {
    /**
     * 注冊自動解析器Bean
     * AutoDetectParser:自動識別文件格式,無需手動指定解析器
     * 線程安全,全局單例使用即可
     */
    @Bean
    public AutoDetectParser detectParser() {
        // 默認(rèn)配置適配絕大多數(shù)場景,可自定義編碼、超時、解析規(guī)則
        return new AutoDetectParser();
    }
}

2. 文件解析結(jié)果對象實體類封裝

新建文件信息實體類,統(tǒng)一封裝解析文本和元數(shù)據(jù),方便接口返回和業(yè)務(wù)層調(diào)用。

import lombok.Builder;
import lombok.Data;
import java.util.Map;
/**
 * 文件解析結(jié)果實體
 * 統(tǒng)一封裝:提取的文本內(nèi)容 + 文件元數(shù)據(jù),標(biāo)準(zhǔn)化返回格式
 */
@Data
@Builder
public class FileInfo {
    /**
     * 從文件中提取的純文本內(nèi)容
     */
    private String fileText;
    /**
     * 文件元數(shù)據(jù)集合
     * Key:元數(shù)據(jù)字段名(如Content-Type、Author、Creation-Date)
     * Value:對應(yīng)字段值
     */
    private Map<String,Object> metadata;
}

3. 核心服務(wù)類:覆蓋高頻解析場景

封裝通用文件解析方法,內(nèi)置10MB緩沖區(qū)閾值,兼顧大文件解析和內(nèi)存控制。

import com.example.springboot3tikademo.entity.FileInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.tika.exception.TikaException;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.parser.AutoDetectParser;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.sax.BodyContentHandler;
import org.springframework.stereotype.Service;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
/**
 * 文件解析核心業(yè)務(wù)類
 * 封裝統(tǒng)一解析邏輯,處理普通/大文件、元數(shù)據(jù)轉(zhuǎn)換、異常捕獲
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class FileDetectService {
    /**
     * 注入自動解析器單例
     */
    private final AutoDetectParser detectParser;
    /**
     * 統(tǒng)一文件解析入口
     * @param inputStream 文件輸入流(前端上傳/本地文件均可)
     * @return FileInfo 封裝后的解析結(jié)果
     */
    public FileInfo parseFile(InputStream inputStream) {
        // 入?yún)⒎强招r灒乐箍罩羔?
        if (inputStream == null) {
            throw new IllegalArgumentException("文件輸入流不能為空,請檢查文件上傳狀態(tài)");
        }
        try {
            // 設(shè)置10MB緩沖區(qū),平衡解析速度與內(nèi)存占用,防止OOM
            ContentHandler handler = new BodyContentHandler(10 * 1024 * 1024);
            // 元數(shù)據(jù)對象:存儲文件類型、作者、創(chuàng)建時間等屬性
            Metadata metadata = new Metadata();
            // 解析上下文:用于擴展自定義解析規(guī)則、傳參
            ParseContext context = new ParseContext();
            // 執(zhí)行文件解析核心邏輯
            detectParser.parse(inputStream, handler, metadata, context);
            // Metadata對象無法直接序列化,轉(zhuǎn)為HashMap適配接口返回
            Map<String,Object> metadataMap = new HashMap<>();
            for (String name : metadata.names()){
                metadataMap.put(name, metadata.get(name));
            }
            // 構(gòu)建結(jié)果對象返回
            return FileInfo.builder()
                    .fileText(handler.toString())
                    .metadata(metadataMap)
                    .build();
        } catch (SAXException | TikaException | IOException e) {
            // 打印詳細(xì)異常日志,方便線上排查問題
            log.error("文件解析失敗,異常堆棧:", e);
            return null;
        }
    }
}

4. 接口開發(fā):場景化測試調(diào)用

編寫文件上傳解析接口,接收前端上傳文件,調(diào)用核心服務(wù)完成解析,返回結(jié)構(gòu)化JSON數(shù)據(jù),方便自測和前端對接;后續(xù)可在此基礎(chǔ)上擴展單獨的文件類型校驗接口。

import com.alibaba.fastjson2.JSONObject;
import com.example.springboot3tikademo.entity.FileInfo;
import com.example.springboot3tikademo.service.FileDetectService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
/**
 * 文件解析接口控制器
 * 對外提供HTTP接口,對接前端文件上傳與解析請求
 */
@Slf4j
@RestController
@RequestMapping("/api/file")
@RequiredArgsConstructor
public class FileController {
    /**
     * 注入文件解析服務(wù)
     */
    private final FileDetectService fileDetectService;
    /**
     * 文件上傳 + 全量解析接口
     * @param file 前端上傳的文件對象
     * @return JSONObject 標(biāo)準(zhǔn)化響應(yīng)結(jié)果(狀態(tài)碼+提示+數(shù)據(jù))
     */
    @PostMapping("/parse")
    public JSONObject parseFile(@RequestParam("file") MultipartFile file) {
        // 第一步:校驗文件是否為空
        if (file.isEmpty()) {
            return JSONObject.of("code", 500, "msg", "上傳文件不能為空,請選擇文件后重試");
        }
        // try-with-resources:自動關(guān)閉輸入流,避免資源泄漏
        try (InputStream inputStream = file.getInputStream()) {
            // 調(diào)用服務(wù)層執(zhí)行解析
            FileInfo fileInfo = fileDetectService.parseFile(inputStream);
            // 解析失敗返回友好提示
            if (fileInfo == null) {
                return JSONObject.of("code", 500, "msg", "文件解析失敗,請檢查文件格式是否支持或文件是否損壞");
            }
            // 封裝成功響應(yīng):拼接狀態(tài)碼、提示、文件名、解析數(shù)據(jù)
            JSONObject result = JSONObject.from(fileInfo);
            result.put("code", 200);
            result.put("msg", "文件解析成功");
            result.put("fileName", file.getOriginalFilename());
            return result;
        } catch (Exception e) {
            // 打印異常日志,定位上傳/解析流程問題
            log.error("文件上傳解析異常,文件名:{}", file.getOriginalFilename(), e);
            return JSONObject.of("code", 500, "msg", "解析異常:" + e.getMessage());
        }
    }
}

三、接口測試:驗證解析效果

項目啟動后,用Postman或者接口測試工具調(diào)用:

  • 請求地址:POST localhost:8080/api/file/parse
  • 請求方式:form-data,key設(shè)為file,選擇本地文檔(.doc/.docx/.pdf/.txt/.xlsx)
  • 返回結(jié)果:結(jié)構(gòu)化JSON,包含文件名、響應(yīng)狀態(tài)、提取文本、元數(shù)據(jù)(作者、文件類型、創(chuàng)建時間等)

實測主流辦公格式都能正常解析,元數(shù)據(jù)完整不丟失,文本提取精準(zhǔn),不會出現(xiàn)亂碼、內(nèi)容截斷問題。

四、常見問題與調(diào)優(yōu)

1. 大文件解析報錯:Write limit exceeded

當(dāng)前代碼已設(shè)置10MB緩沖區(qū),若需解析更大文件,直接調(diào)整BodyContentHandler數(shù)值即可;比如設(shè)置100MB閾值:new BodyContentHandler(100 * 1024 * 1024),不建議設(shè)為-1無限制,避免服務(wù)器OOM。

2. PDF中文亂碼

解析PDF出現(xiàn)中文亂碼,優(yōu)先排查兩點:一是服務(wù)器安裝對應(yīng)中文字體包,二是在解析前手動指定UTF-8編碼,在Metadata中添加配置:

// 解析前手動指定UTF-8編碼,解決PDF中文亂碼、字符集不兼容問題
metadata.set(Metadata.CONTENT_ENCODING, "UTF-8");

3. 文件類型安全校驗

嚴(yán)禁只靠文件名后綴判斷文件類型,惡意文件篡改后綴極易繞過校驗。可從元數(shù)據(jù)中提取真實MIME類型,做白名單校驗,攔截非法文件上傳:

// 1. 從元數(shù)據(jù)獲取文件真實MIME類型,不依賴文件名后綴
String mimeType = (String) metadataMap.get("Content-Type");
// 2. 定義允許上傳的文件白名單,可根據(jù)業(yè)務(wù)擴展(如Excel、PPT)
List<String> allowTypes = Arrays.asList(
        "application/pdf",                      // PDF格式
        "application/msword",                  // Doc舊版Word
        "application/vnd.openxmlformats-officedocument.wordprocessingml.document", // Docx新版Word
        "text/plain"                           // TXT純文本
);
// 3. 白名單校驗,攔截非法文件,防止惡意上傳
if (!allowTypes.contains(mimeType)) {
    throw new RuntimeException("不支持該文件類型,請上傳PDF/Word/TXT格式文檔");
}

4. 生產(chǎn)性能優(yōu)化

  • 超大文件(100MB+)建議采用異步解析,避免接口超時阻塞主線程
  • 對重復(fù)上傳文件做MD5緩存,復(fù)用解析結(jié)果,減少重復(fù)計算
  • 配置SpringBoot文件上傳大小限制,防止惡意大文件攻擊
  • 文件流務(wù)必使用try-with-resources自動關(guān)閉,避免資源泄漏

五、總結(jié)

這套SpringBoot3集成方案,配置簡單,代碼量小、侵入性極低,通過單例注入、標(biāo)準(zhǔn)化封裝、統(tǒng)一解析,實現(xiàn)了多格式文件文本提取+元數(shù)據(jù)獲取一站式搞定,完美適配內(nèi)容審核、文檔管理、數(shù)據(jù)錄入、全文檢索等業(yè)務(wù)場景。

除了基礎(chǔ)的文檔解析,Apache Tika還支持音視頻文件元數(shù)據(jù)提取、圖片文本OCR識別、壓縮包內(nèi)容遍歷、加密文檔解密等擴展能力,后續(xù)想疊加這些高階功能,原有代碼結(jié)構(gòu)無需改動,直接擴展方法即可,兼容性和擴展性拉滿。

以上就是SpringBoot3使用Apache Tika實現(xiàn)多格式文件內(nèi)容提取的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot3多格式文件內(nèi)容提取的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論

礼泉县| 长宁县| 垦利县| 贵港市| 双鸭山市| 平江县| 普定县| 筠连县| 绿春县| 北宁市| 拜城县| 高雄县| 平塘县| 阜康市| 吉木乃县| 边坝县| 扎囊县| 金坛市| 仪征市| 兴和县| 兰考县| 营口市| 丹东市| 赫章县| 大余县| 灵武市| 丰顺县| 虞城县| 高邑县| 乐平市| 大方县| 皮山县| 勃利县| 石阡县| 察隅县| 安图县| 塘沽区| 保亭| 龙口市| 黎川县| 西城区|