亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

使用Spring?Boot快速構建一個簡單的文件處理工具

 更新時間:2025年06月03日 08:56:43   作者:碼農阿豪@新空間  
在現代Web應用中,文件上傳與處理是常見的需求,本文將通過一個實際案例,詳細介紹如何使用Spring?Boot構建一個文件處理工具,感興趣的小伙伴可以參考一下

引言

在現代Web應用中,文件上傳與處理是常見的需求。本文將通過一個實際案例,詳細介紹如何使用Spring Boot構建一個文件處理工具,實現以下功能:

  • 接收用戶上傳的ZIP壓縮包
  • 解壓ZIP文件并提取其中的圖片
  • 使用OCR技術識別圖片中的關鍵信息
  • 將識別結果導出為Excel文件
  • 同時保存結果到服務器本地

我們將從項目搭建、核心功能實現到錯誤處理等方面進行全面講解,并提供完整的代碼示例。

一、項目概述與搭建

1.1 功能需求

用戶通過網頁上傳ZIP文件

后端解壓ZIP,提取圖片文件

對每張圖片進行OCR識別(如快遞單號、手機號)

將識別結果生成Excel并提供下載

在服務器resources/output目錄保留結果副本

1.2 技術棧

后端:Spring Boot 2.7+

模板引擎:Thymeleaf(前后端不分離)

文件處理:Apache Commons Compress(ZIP解壓)

OCR識別:百度OCR API(或其他OCR服務)

Excel操作:Apache POI

1.3 初始化項目

使用Spring Initializr創(chuàng)建項目,添加依賴:

<dependencies>
    <!-- Web支持 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <!-- 模板引擎 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    
    <!-- Excel操作 -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>5.2.3</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>5.2.3</version>
    </dependency>
    
    <!-- 文件上傳 -->
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.11.0</version>
    </dependency>
</dependencies>

二、核心功能實現

2.1 文件上傳接口

2.2 ZIP解壓實現

private List<File> unzipFile(MultipartFile file) throws IOException {
    List<File> extractedFiles = new ArrayList<>();
    Path tempDir = Files.createTempDirectory("unzip_");
    
    try (ZipInputStream zipIn = new ZipInputStream(file.getInputStream())) {
        ZipEntry entry;
        while ((entry = zipIn.getNextEntry()) != null) {
            Path filePath = tempDir.resolve(entry.getName());
            
            // 防止ZIP滑動攻擊
            if (!filePath.normalize().startsWith(tempDir)) {
                throw new SecurityException("非法文件路徑");
            }
            
            if (!entry.isDirectory() && isImageFile(entry.getName())) {
                Files.copy(zipIn, filePath);
                extractedFiles.add(filePath.toFile());
            }
            zipIn.closeEntry();
        }
    }
    return extractedFiles;
}
???????private boolean isImageFile(String filename) {
    String[] extensions = {".jpg", ".png", ".jpeg"};
    return Arrays.stream(extensions).anyMatch(filename::endsWith);
}

2.3 OCR信息識別

public OrderInfo getPicInfo(String imagePath) {
    OrderInfo info = new OrderInfo();
    try {
        String base64Image = imageToBase64(imagePath);
        String ocrResult = callOcrApi(base64Image); // 調用OCR API
        info.setExpressNumber(extractExpressNo(ocrResult));
        info.setPhoneNumber(extractPhoneNo(ocrResult));
    } catch (Exception e) {
        info.setError(true);
    }
    return info;
}

2.4 生成Excel并保存

private void saveToResourcesOutput(Workbook workbook) throws IOException {
    Path outputDir = Paths.get("src/main/resources/output");
    if (!Files.exists(outputDir)) {
        Files.createDirectories(outputDir);
    }
    
    String filename = "result_" + System.currentTimeMillis() + ".xlsx";
    try (FileOutputStream out = new FileOutputStream(outputDir.resolve(filename).toFile())) {
        workbook.write(out);
    }
}

三、前端頁面實現

Thymeleaf模板(index.html)

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>圖片處理工具</title>
</head>
<body>
    <h1>上傳ZIP壓縮包</h1>
    <form method="post" action="/upload" enctype="multipart/form-data">
        <input type="file" name="file" accept=".zip" required>
        <button type="submit">提交</button>
    </form>
    
    <div th:if="${message}" th:text="${message}"></div>
</body>
</html>

四、錯誤處理與優(yōu)化

4.1 常見錯誤解決

問題1:Thymeleaf模板找不到

Error resolving template [index], template might not exist

解決方案:

  • 確認index.html位于resources/templates/目錄
  • 檢查是否添加了Thymeleaf依賴
  • 確??刂破鞣祷氐囊晥D名稱匹配

問題2:ZIP解壓失敗

增強健壯性:

try {
    unzipFile(file);
} catch (IOException e) {
    log.error("解壓失敗", e);
    throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "無效的ZIP文件");
}

4.2 性能優(yōu)化建議

大文件處理:使用SXSSFWorkbook流式寫入Excel

并發(fā)處理:對多圖片采用線程池并行OCR識別

臨時文件清理:

@Scheduled(fixedRate = 86400000) // 每天清理
public void cleanTempFiles() {
    // 刪除超過1天的臨時文件
}

五、問題分析與解決方案

問題描述

用戶在使用Spring Boot開發(fā)一個文件處理應用時,遇到以下兩個主要問題:

  • 中文文件名處理失?。荷蟼靼形奈募腪IP文件時,報錯MALFORMED。
  • JAR包無法運行:使用java -jar啟動時提示no main manifest attribute,手動指定主類后,又報NoClassDefFoundError。

環(huán)境信息

Spring Boot版本:2.6.13

JDK版本:1.8

構建工具:Maven

問題場景:文件上傳解析 + 生成Excel

問題分析

1.中文文件名處理失?。∕ALFORMED錯誤)

問題原因

  • 在解壓ZIP文件時,ZipInputStream默認使用的編碼可能與ZIP文件的實際編碼不一致,導致中文文件名解析錯誤。
  • 路徑安全檢查不完善,可能引發(fā)安全漏洞(如ZIP路徑遍歷攻擊)。

解決方案

優(yōu)化unzipFile方法,正確處理編碼和路徑安全:

private List<File> unzipFile(MultipartFile file) throws IOException {
    List<File> extractedFiles = new ArrayList<>();
    File tempDir = Files.createTempDirectory("unzip_").toFile();
    tempDir.deleteOnExit();

    // 嘗試GBK編碼(常見于Windows生成的ZIP)
    try (ZipInputStream zipIn = new ZipInputStream(file.getInputStream(), Charset.forName("GBK"))) {
        ZipEntry entry;
        while ((entry = zipIn.getNextEntry()) != null) {
            String entryName = entry.getName();
            File destFile = new File(tempDir, entryName);
            
            // 安全檢查:防止ZIP路徑遍歷
            String canonicalPath = destFile.getCanonicalPath();
            if (!canonicalPath.startsWith(tempDir.getCanonicalPath() + File.separator)) {
                throw new SecurityException("ZIP文件包含非法路徑: " + entryName);
            }

            if (!entry.isDirectory() && isImageFile(entryName)) {
                Files.createDirectories(destFile.getParentFile().toPath());
                Files.copy(zipIn, destFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
                extractedFiles.add(destFile);
            }
            zipIn.closeEntry();
        }
    } catch (Exception e) {
        // 如果GBK失敗,回退到UTF-8
        try (ZipInputStream zipIn = new ZipInputStream(file.getInputStream(), StandardCharsets.UTF_8)) {
            // 重復解壓邏輯...
        }
    }
    return extractedFiles;
}

關鍵改進點

多編碼支持:優(yōu)先嘗試GBK(常見中文編碼),失敗后回退到UTF-8。

路徑安全:使用getCanonicalPath檢查路徑合法性,防止惡意ZIP文件攻擊。

代碼健壯性:使用Files.copy替代手動緩沖讀寫,更高效可靠。

2.JAR包無法運行(NoClassDefFoundError)

問題原因

打包時未正確生成可執(zhí)行的Spring Boot JAR,導致:

  • 缺少MANIFEST.MF中的Main-Class。
  • 依賴庫未打包進JAR(BOOT-INF/lib缺失)。

解決方案

修正pom.xml,確保正確打包:

<build>
    <plugins>
        <!-- 1. 指定Java編譯版本 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <encoding>UTF-8</encoding>
            </configuration>
        </plugin>

        <!-- 2. 關鍵:正確配置Spring Boot Maven插件 -->
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>${spring-boot.version}</version>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal> <!-- 生成可執(zhí)行JAR -->
                    </goals>
                </execution>
            </executions>
            <configuration>
                <mainClass>com.debang.debang_phone_tool.DebangPhoneToolApplication</mainClass>
            </configuration>
        </plugin>
    </plugins>
</build>

關鍵改進點

移除<skip>true</skip>:確保插件執(zhí)行重新打包操作。

明確指定mainClass:避免運行時找不到主類。

驗證打包結果

# 檢查JAR結構
jar tf target/debang_phone_tool-0.0.1-SNAPSHOT.jar | grep BOOT-INF/lib
# 檢查MANIFEST.MF
jar xf target/debang_phone_tool-0.0.1-SNAPSHOT.jar META-INF/MANIFEST.MF && cat META-INF/MANIFEST.MF

完整解決方案

修正后的項目結構

src/
├── main/
│   ├── java/
│   │   └── com/debang/debang_phone_tool/
│   │       ├── DebangPhoneToolApplication.java  # Spring Boot主類
│   │       ├── controller/                      # 控制器
│   │       └── service/                         # 業(yè)務邏輯
│   └── resources/
│       ├── static/                              # 靜態(tài)文件
│       └── application.yml                      # 配置文件
pom.xml                                         # 修正后的Maven配置

打包與運行命令

# 清理并重新打包
mvn clean package

# 后臺運行(Linux)
nohup java -jar target/debang_phone_tool-0.0.1-SNAPSHOT.jar > app.log 2>&1 &

# 查看日志
tail -f app.log

總結

1.編碼問題

文件處理:顯式指定編碼(如GBK/UTF-8),避免依賴平臺默認值。

路徑安全:使用getCanonicalPath檢查路徑合法性。

2.打包問題

必須使用spring-boot-maven-plugin:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
</plugin>

驗證JAR結構:

  • 確保存在BOOT-INF/lib(依賴庫)和META-INF/MANIFEST.MF。
  • 避免<skip>true</skip>:否則會導致依賴未打包。

3.日志與監(jiān)控

日志重定向:使用2>&1捕獲所有輸出:

nohup java -jar app.jar > app.log 2>&1 &

進程管理:結合systemd或supervisord實現服務化。

六、總結

本文實現了一個完整的Spring Boot文件處理流程,關鍵點包括:

  • 使用MultipartFile接收上傳文件
  • 安全的ZIP解壓與路徑校驗
  • 第三方OCR服務集成
  • 動態(tài)Excel生成與雙存儲(下載+本地保存)
  • 全面的異常處理機制

擴展方向:

  • 添加用戶系統(tǒng),隔離不同用戶的數據
  • 支持更多文件格式(如RAR、7z)
  • 集成更強大的OCR引擎(如Tesseract)

GitHub示例:完整代碼可在 https://github.com/example/file-processor 獲取

通過這個案例,讀者可以掌握Spring Boot中文件處理的核心技術,并快速應用到實際項目中。

以上就是使用Spring Boot快速構建一個簡單的文件處理工具的詳細內容,更多關于Spring Boot文件處理的資料請關注腳本之家其它相關文章!

相關文章

  • Java BIO,NIO,AIO總結

    Java BIO,NIO,AIO總結

    這篇文章主要介紹了Java BIO,NIO,AIO的相關資料,幫助大家更好的理解和學習Java,感興趣的朋友可以了解下
    2020-09-09
  • @Autowired注解在抽象類中失效的原因及解決

    @Autowired注解在抽象類中失效的原因及解決

    這篇文章主要介紹了@Autowired注解在抽象類中失效的原因及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • java 判斷字符串是否包含子串的方法

    java 判斷字符串是否包含子串的方法

    這篇文章主要介紹了java 判斷字符串是否包含子串的方法的相關資料,這里提供了三種方法幫助大家實現這樣的功能,需要的朋友可以參考下
    2017-08-08
  • Java異常ClassCastException的解決

    Java異常ClassCastException的解決

    這篇文章主要介紹了Java異常ClassCastException的解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-11-11
  • Java如何導出多個excel并打包壓縮成.zip文件

    Java如何導出多個excel并打包壓縮成.zip文件

    本文介紹了Java如何導出多個excel文件并將這些文件打包壓縮成zip格式,首先,需要從數據庫中獲取數據并導出到指定位置形成excel文件,接著,將這些數據分散到不同的excel文件中,最后,使用相關的Java工具類對這些excel文件進行打包壓縮
    2024-09-09
  • JAVA利用HttpClient進行POST請求(HTTPS)實例

    JAVA利用HttpClient進行POST請求(HTTPS)實例

    下面小編就為大家?guī)硪黄狫AVA利用HttpClient進行POST請求(HTTPS)實例。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起 小編過來看看吧
    2016-11-11
  • Java基礎之List內元素的排序性能對比

    Java基礎之List內元素的排序性能對比

    這篇文章主要介紹了Java基礎之List內元素的排序性能對比,文中有非常詳細的代碼示例,對正在學習java基礎的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04
  • Java非靜態(tài)成員變量之死循環(huán)(詳解)

    Java非靜態(tài)成員變量之死循環(huán)(詳解)

    下面小編就為大家?guī)硪黄狫ava非靜態(tài)成員變量之死循環(huán)(詳解)。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • Kotlin基礎教程之面向對象

    Kotlin基礎教程之面向對象

    這篇文章主要介紹了Kotlin基礎教程之面向對象的相關資料,需要的朋友可以參考下
    2017-05-05
  • Java?的訪問修飾符public,protected,private(封裝、繼承)

    Java?的訪問修飾符public,protected,private(封裝、繼承)

    這篇文章主要介紹了Java?的訪問修飾符public,protected,private(封裝、繼承),文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-09-09

最新評論