Spring Boot 實戰:輕松實現文件上傳與下載功能

目錄

一、引言

二、Spring Boot 文件上傳基礎

(一)依賴引入

(二)配置文件設置

(三)文件上傳接口編寫

(一)文件類型限制

(二)文件大小驗證

(三)防止文件覆蓋

四、Spring Boot 文件下載實現

(一)簡單文件下載接口編寫

(二)文件下載的異常處理

(三)支持斷點續傳

五、實戰案例演示

六、總結與展望


一、引言

在當今的 Web 應用開發中,文件上傳與下載功能是極為常見且重要的需求。無論是用戶上傳頭像、分享文檔,還是系統生成報告供用戶下載,都離不開這一功能模塊。Spring Boot 作為一款流行的 Java 開發框架,為我們提供了簡潔高效的方式來實現文件上傳與下載。本文將詳細介紹如何基于 Spring Boot 框架輕松搭建并實現這一功能,讓你快速掌握其核心要點與實踐技巧。

二、Spring Boot 文件上傳基礎

(一)依賴引入

在 Spring Boot 項目中,首先需要引入相關依賴。對于文件上傳功能,除了基礎的spring-boot-starter-web依賴外,還需要添加處理文件上傳的commons-fileupload依賴。在pom.xml文件中添加如下依賴:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.4</version>
</dependency>

spring-boot-starter-web提供了構建 Web 應用的基礎功能,而commons-fileupload則專門用于處理文件上傳操作。

(二)配置文件設置

application.properties配置文件中設置與文件上傳相關的參數。例如:

?
# 設置單個文件上傳的最大大小為 10MB
spring.servlet.multipart.max-file-size=10MB
# 設置一次請求中上傳文件的總大小為 20MB
spring.servlet.multipart.max-request-size=20MB
# 設置上傳文件的臨時目錄
spring.servlet.multipart.location=/tmp/uploads?

這里分別設置了單個文件大小限制、總請求文件大小限制以及上傳文件的臨時存儲目錄。這些配置可以根據實際項目需求進行調整。

(三)文件上傳接口編寫

編寫一個簡單的文件上傳接口,接收前端傳來的文件數據。創建一個FileUploadController類:

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;import java.io.File;
import java.io.IOException;@RestController
public class FileUploadController {@PostMapping("/upload")public String uploadFile(@RequestParam("file") MultipartFile file) {if (file.isEmpty()) {return "上傳文件為空,請選擇文件后再次上傳。";}try {// 獲取文件名String fileName = file.getOriginalFilename();// 獲取文件存儲路徑,這里假設存儲在項目根目錄下的 uploads 文件夾中String filePath = System.getProperty("user.dir") + "/uploads/" + fileName;// 將文件保存到指定路徑file.transferTo(new File(filePath));return "文件上傳成功,文件路徑:" + filePath;} catch (IOException e) {e.printStackTrace();return "文件上傳失敗:" + e.getMessage();}}
}

在上述代碼中,@RestController表示這是一個處理 RESTful 風格請求的控制器類。@PostMapping("/upload")注解指定了該方法處理POST請求到/upload路徑的邏輯。@RequestParam("file") MultipartFile file用于接收前端傳來的名為file的文件數據。通過file.isEmpty()判斷文件是否為空,如果不為空,則獲取文件的原始名稱getOriginalFilename(),構建文件存儲路徑,最后使用transferTo()方法將文件保存到指定路徑。如果保存過程中出現IOException異常,則打印異常信息并返回錯誤提示。

(一)文件類型限制

可以通過白名單的方式對上傳文件的類型進行限制。例如,只允許上傳圖片文件(如.jpg.png.gif):

private static final String[] ALLOWED_FILE_TYPES = { "image/jpeg", "image/png", "image/gif" };@PostMapping("/upload")
public String uploadFile(@RequestParam("file") MultipartFile file) {if (file.isEmpty()) {return "上傳文件為空,請選擇文件后再次上傳。";}// 檢查文件類型是否在允許列表中if (!Arrays.asList(ALLOWED_FILE_TYPES).contains(file.getContentType())) {return "不允許上傳該類型的文件,請上傳圖片文件(jpg、png、gif)。";}try {// 后續文件保存邏輯...} catch (IOException e) {e.printStackTrace();return "文件上傳失敗:" + e.getMessage();}
}

上述代碼中,定義了一個允許的文件類型數組ALLOWED_FILE_TYPES,然后在上傳文件前檢查文件的ContentType是否在允許列表中,如果不在,則返回錯誤提示。

(二)文件大小驗證

除了配置文件中的全局限制,在代碼層面也可以再次驗證單個文件大小:

@PostMapping("/upload")
public String uploadFile(@RequestParam("file") MultipartFile file) {if (file.isEmpty()) {return "上傳文件為空,請選擇文件后再次上傳。";}// 檢查文件大小是否超過 5MBif (file.getSize() > 5 * 1024 * 1024) {return "上傳文件過大,單個文件大小不能超過 5MB。";}// 后續文件類型檢查及保存邏輯...
}

這里通過file.getSize()獲取文件大小,并與設定的限制(5MB)進行比較,如果超過則返回錯誤提示。

(三)防止文件覆蓋

采用時間戳生成唯一文件名來防止文件覆蓋:

@PostMapping("/upload")
public String uploadFile(@RequestParam("file") MultipartFile file) {if (file.isEmpty()) {return "上傳文件為空,請選擇文件后再次上傳。";}try {// 獲取文件名String originalFileName = file.getOriginalFilename();// 獲取文件后綴名String fileExtension = originalFileName.substring(originalFileName.lastIndexOf("."));// 生成唯一文件名,使用當前時間戳String uniqueFileName = System.currentTimeMillis() + fileExtension;// 獲取文件存儲路徑,這里假設存儲在項目根目錄下的 uploads 文件夾中String filePath = System.getProperty("user.dir") + "/uploads/" + uniqueFileName;// 將文件保存到指定路徑file.transferTo(new File(filePath));return "文件上傳成功,文件路徑:" + filePath;} catch (IOException e) {e.printStackTrace();return "文件上傳失敗:" + e.getMessage();}
}

通過獲取原始文件名的后綴名,結合當前時間戳生成一個唯一的文件名,確保每次上傳的文件都有獨立的標識,避免覆蓋同名文件。

四、Spring Boot 文件下載實現

(一)簡單文件下載接口編寫

創建一個文件下載接口,如下:

import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import java.io.File;@RestController
public class FileDownloadController {@GetMapping("/download")public ResponseEntity<FileSystemResource> downloadFile(@RequestParam("fileName") String fileName) {// 獲取文件路徑,這里假設文件存儲在項目根目錄下的 uploads 文件夾中String filePath = System.getProperty("user.dir") + "/uploads/" + fileName;File file = new File(filePath);if (file.exists()) {// 設置響應頭信息,包括文件名和文件類型HttpHeaders headers = new HttpHeaders();headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + fileName);headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE);// 返回文件資源return ResponseEntity.ok().headers(headers).body(new FileSystemResource(file));} else {return ResponseEntity.notFound().build();}}
}

在這個代碼中,@GetMapping("/download")表示處理GET請求到/download路徑的邏輯。根據前端傳入的文件名參數fileName,構建文件路徑并檢查文件是否存在。如果存在,則設置響應頭信息,包括Content-Disposition用于指定文件名和下載方式(attachment表示下載),Content-Type設置為APPLICATION_OCTET_STREAM_VALUE表示通用的二進制流文件類型。最后通過ResponseEntity返回文件資源,若文件不存在則返回404 Not Found狀態。

(二)文件下載的異常處理

在上述代碼中,如果文件不存在則返回404狀態。還可以進一步處理其他可能的異常,例如文件讀取錯誤:

@GetMapping("/download")
public ResponseEntity<FileSystemResource> downloadFile(@RequestParam("fileName") String fileName) {String filePath = System.getProperty("user.dir") + "/uploads/" + fileName;File file;try {file = new File(filePath);if (file.exists()) {// 設置響應頭信息...return ResponseEntity.ok().headers(headers).body(new FileSystemResource(file));} else {return ResponseEntity.notFound().build();}} catch (Exception e) {e.printStackTrace();return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();}
}

這里捕獲了可能出現的異常,并在異常發生時返回500 Internal Server Error狀態碼,表示服務器內部錯誤。

(三)支持斷點續傳

對于大文件下載實現斷點續傳功能:

@GetMapping("/download")
public ResponseEntity<Resource> downloadFile(@RequestParam("fileName") String fileName,@RequestHeader(value = "Range", required = false) String rangeHeader) {String filePath = System.getProperty("user.dir") + "/uploads/" + fileName;File file = new File(filePath);if (file.exists()) {try {// 獲取文件長度long fileLength = file.length();// 處理 Range 請求頭HttpHeaders headers = new HttpHeaders();if (rangeHeader!= null && rangeHeader.startsWith("bytes=")) {long startRange = Long.parseLong(rangeHeader.substring("bytes=".length()).split("-")[0]);long endRange = fileLength - 1;if (rangeHeader.contains("-")) {endRange = Long.parseLong(rangeHeader.substring("bytes=".length()).split("-")[1]);}// 設置響應頭的 Content-Range 字段headers.add(HttpHeaders.CONTENT_RANGE, "bytes " + startRange + "-" + endRange + "/" + fileLength);headers.add(HttpHeaders.CONTENT_LENGTH, String.valueOf(endRange - startRange + 1));headers.add(HttpHeaders.ACCEPT_RANGES, "bytes");// 設置響應狀態碼為 206 Partial Contentreturn ResponseEntity.status(HttpStatus.PARTIAL_CONTENT).headers(headers).body(new FileSystemResource(file).createRelative(startRange, endRange));} else {headers.add(HttpHeaders.CONTENT_LENGTH, String.valueOf(fileLength));headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE);headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + fileName);return ResponseEntity.ok().headers(headers).body(new FileSystemResource(file));}} catch (Exception e) {e.printStackTrace();return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();}} else {return ResponseEntity.notFound().build();}
}

在上述代碼中,首先獲取文件的總長度fileLength。然后檢查請求頭中的Range信息,如果存在Range請求,則解析出起始和結束位置startRangeendRange,設置響應頭的Content-RangeContent-LengthACCEPT_RANGES字段,并返回206 Partial Content狀態碼,表示部分內容響應,同時通過createRelative()方法讀取文件指定范圍的數據返回給客戶端。如果沒有Range請求,則按照普通下載方式設置響應頭并返回整個文件。

五、實戰案例演示

通過一個完整的 Spring Boot 項目實例,演示文件上傳與下載功能的實際應用。包括前端頁面的設計與交互(使用 HTML、JavaScript 等前端技術實現簡單的文件上傳和下載按鈕及相關提示信息),以及后端 Spring Boot 代碼的具體實現細節。展示如何將文件上傳與業務邏輯相結合,例如在用戶注冊時上傳頭像,并在用戶個人資料頁面實現頭像的下載顯示;或者在一個文檔管理系統中,實現文件的上傳、分類存儲以及用戶按需下載等功能場景。

六、總結與展望

總結本文所介紹的 Spring Boot 文件上傳與下載功能的實現步驟、關鍵要點以及注意事項。強調在實際開發過程中,安全性與穩定性是至關重要的因素,需要開發者充分考慮各種邊界情況并進行合理的處理。同時,展望未來可能的擴展方向,如與云存儲服務集成,實現更強大、靈活的文件管理功能,以滿足日益增長的業務需求。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/70046.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/70046.shtml
英文地址,請注明出處:http://en.pswp.cn/web/70046.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Golang】GC探秘/寫屏障是什么?

之前寫了 一篇【Golang】內存管理 &#xff0c;有了很多的閱讀量&#xff0c;那么我就接著分享一下Golang的GC相關的學習。 由于Golang的GC機制一直在持續迭代&#xff0c;本文敘述的主要是Go1.9版本及以后的GC機制&#xff0c;該版本中Golang引入了 混合寫屏障大幅度地優化了S…

DeepSeek教unity------MessagePack-03

數據契約兼容性 你可以使用 [DataContract] 注解代替 [MessagePackObject]。如果類型用 DataContract 進行注解&#xff0c;可以使用 [DataMember] 注解代替 [Key]&#xff0c;并使用 [IgnoreDataMember] 代替 [IgnoreMember]。 然后&#xff0c;[DataMember(Order int)] 的…

【對比】Pandas 和 Polars 的區別

Pandas vs Polars 對比表 特性PandasPolars開發語言Python&#xff08;Cython 實現核心部分&#xff09;Rust&#xff08;高性能系統編程語言&#xff09;性能較慢&#xff0c;尤其在大數據集上&#xff08;內存占用高&#xff0c;計算效率低&#xff09;極快&#xff0c;利用…

百度千帆平臺對接DeepSeek官方文檔

目錄 第一步&#xff1a;注冊賬號&#xff0c;開通千帆服務 第二步&#xff1a;創建應用&#xff0c;獲取調用秘鑰 第三步&#xff1a;調用模型&#xff0c;開啟AI對話 方式一&#xff1a;通過API直接調用 方式二&#xff1a;使用SDK快速調用 方式三&#xff1a;在千帆大模…

49. c++計時器

為了測試某段特定代碼的執行時間&#xff0c;體現代碼的性能&#xff0c;可以使用計時器對代碼段計時。下面使用std::chrono中的api編寫簡單案例&#xff1a; // // main.cpp // HelloWorld // // Created by on 2024/11/28. //#include <iostream> #include <vec…

Natural Language Processing NLP

NLP 清晰版本查看 Sentence segmentation (split)Tokenisation (split)Named entity recognition (combine) 概念主要內容典型方法Distributional Semantics&#xff08;分佈式語義&#xff09;&#xff08;分銷語義&#xff08;分佈式語義&#xff09;單詞的語義來自於它的…

Linux中線程創建,線程退出,線程接合

線程的簡單了解 之前我們了解過 task_struct 是用于描述進程的核心數據結構。它包含了一個進程的所有重要信息&#xff0c;并且在進程的生命周期內保持更新。我們想要獲取進程相關信息往往從這里得到。 在Linux中&#xff0c;線程的實現方式與進程類似&#xff0c;每個線程都…

HarmonyOS:使用List實現分組列表(包含粘性標題)

一、支持分組列表 在列表中支持數據的分組展示&#xff0c;可以使列表顯示結構清晰&#xff0c;查找方便&#xff0c;從而提高使用效率。分組列表在實際應用中十分常見&#xff0c;如下圖所示聯系人列表。 聯系人分組列表 在List組件中使用ListItemGroup對項目進行分組&#…

django上傳文件

1、settings.py配置 # 靜態文件配置 STATIC_URL /static/ STATICFILES_DIRS [BASE_DIR /static, ]上傳文件 # 定義一個視圖函數&#xff0c;該函數接收一個 request 參數 from django.shortcuts import render # 必備引入 import json from django.views.decorators.http i…

【前端知識】瀏覽器兼容方案polyfill

瀏覽器兼容方案polyfill 什么是 Polyfill&#xff1f;Polyfill 的作用Polyfill 的工作原理1. **特性檢測**2. **加載 Polyfill**3. **模擬實現** Polyfill 的常見場景Polyfill 的使用方式Polyfill 的優缺點優點缺點 常見的 Polyfill 庫總結 什么是 Polyfill&#xff1f; Polyf…

C#學習之DateTime 類

目錄 一、DateTime 類的常用方法和屬性的匯總表格 二、常用方法程序示例 1. 獲取當前本地時間 2. 獲取當前 UTC 時間 3. 格式化日期和時間 4. 獲取特定部分的時間 5. 獲取時間戳 6. 獲取時區信息 三、總結 一、DateTime 類的常用方法和屬性的匯總表格 在 C# 中&#x…

dedecms 開放重定向漏洞(附腳本)(CVE-2024-57241)

免責申明: 本文所描述的漏洞及其復現步驟僅供網絡安全研究與教育目的使用。任何人不得將本文提供的信息用于非法目的或未經授權的系統測試。作者不對任何由于使用本文信息而導致的直接或間接損害承擔責任。如涉及侵權,請及時與我們聯系,我們將盡快處理并刪除相關內容。 0x0…

如何選擇合適的超參數來訓練Bert和TextCNN模型?

選擇合適的超參數來訓練Bert和TextCNN模型是一個復雜但關鍵的過程&#xff0c;它會顯著影響模型的性能。以下是一些常見的超參數以及選擇它們的方法&#xff1a; 1. 與數據處理相關的超參數 最大序列長度&#xff08;max_length&#xff09; 含義&#xff1a;指輸入到Bert模…

AWS 前端自動化部署流程指南

本文詳細介紹從前端代碼開發到 AWS 自動化部署的完整流程。 一、流程概覽 1.1 部署流程圖 #mermaid-svg-nYg7k6L5IKVBjDtr {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-nYg7k6L5IKVBjDtr .error-icon{fill:#552…

Office word打開加載比較慢處理方法

1.添加safe參數 ,找到word啟動項,右擊word,選擇屬性 , 添加/safe , 應用并確定 2.取消加載項,點擊文件,點擊選項 ,點擊加載項,點擊轉到,取消所有勾選,確定。

大數據SQL調優專題——Spark執行原理

引入 在深入MapReduce中有提到&#xff0c;MapReduce雖然通過“分而治之”的思想&#xff0c;解決了海量數據的計算處理問題&#xff0c;但性能還是不太理想&#xff0c;這體現在兩個方面&#xff1a; 每個任務都有比較大的overhead&#xff0c;都需要預先把程序復制到各個 w…

MYSQL下載安裝及使用

MYSQL官網下載地址&#xff1a;https://downloads.mysql.com/archives/community/ 也可以直接在服務器執行指令下載&#xff0c;但是下載速度比較慢。還是自己下載好拷貝過來比較快。 wget https://dev.mysql.com/get/Downloads/mysql-5.7.38-linux-glibc2.12-x86_64.tar.gz 1…

CentOS 7.8 安裝MongoDB 7 副本集(Replica Set)

文章目錄 1 環境假設步驟1&#xff1a;在兩臺服務器上安裝MongoDB步驟2&#xff1a;配置副本集步驟3&#xff1a;初始化副本集步驟4&#xff1a;驗證副本集配置步驟5&#xff1a;設置安全性&#xff08;可選&#xff09;擴展配置示例&#xff1a;最佳實踐&#xff1a;仲裁節點步…

AJAX 與 ASP 的深入探討

AJAX 與 ASP 的深入探討 引言 隨著互聯網技術的飛速發展,Web應用程序的交互性和性能要求越來越高。AJAX(Asynchronous JavaScript and XML)和ASP(Active Server Pages)作為兩種重要的Web開發技術,在提高Web應用程序性能和用戶體驗方面發揮著重要作用。本文將深入探討AJ…

內網下,Ubuntu (24.10) 離線安裝docker最新版教程

一般在數據比較敏感的情況下&#xff0c;是無法使用網絡的&#xff0c;而對于Ubuntu系統來說&#xff0c;怎么離線安裝docker呢&#xff1f; 下面我給大家來講一下&#xff1a; 采用二進制安裝&#xff1a; 1.下載docker離線包 官網下載&#xff1a; Index of linux/static…