SpringBoot實(shí)現(xiàn)文件上傳與下載功能的詳細(xì)教程
一、前言
在日常開(kāi)發(fā)中,文件上傳和下載是非常常見(jiàn)的功能場(chǎng)景,比如用戶(hù)頭像上傳、文檔下載、附件管理等。本文將基于 SpringBoot 框架,實(shí)現(xiàn)一套簡(jiǎn)潔、通用、可直接上線(xiàn)使用的文件上傳與下載接口,包含空文件校驗(yàn)、目錄自動(dòng)創(chuàng)建、文件名防重復(fù)、文件不存在處理等核心邏輯。
二、環(huán)境準(zhǔn)備
SpringBoot 版本:2.x/3.x 通用(本文使用 3.x,jakarta 包)
核心依賴(lài):spring-web(Web 開(kāi)發(fā)必備)
配置文件:application.yml/application.properties
三、核心代碼實(shí)現(xiàn)
- pom.xml 依賴(lài)(無(wú)需額外依賴(lài),基礎(chǔ) Web 依賴(lài)即可)
xml
<dependencies>
<!-- SpringBoot Web 核心依賴(lài) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 工具類(lèi)(可選,簡(jiǎn)化開(kāi)發(fā)) -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>- 配置文件(application.yml)
配置文件上傳的存儲(chǔ)目錄,靈活可配置,無(wú)需硬編碼:
yaml
server: port: 8080 #文件上傳配置 file: 上傳文件存儲(chǔ)路徑(Windows:D:/upload Linux:/home/upload) upload-dir: D:/springboot-file-upload
- 文件上傳下載控制器(FileController)
完整整合版代碼,包含上傳 + 下載接口,直接復(fù)制使用:
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
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.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.UUID;
/**
* 文件上傳下載控制器
* @author 你的昵稱(chēng)
*/
@RestController
@RequestMapping("/file")
public class FileController {
// 從配置文件讀取上傳目錄
@Value("${file.upload-dir}")
private String uploadDir;
/**
* 文件上傳接口
* @param file 前端傳遞的文件(form-data 格式)
* @return 上傳結(jié)果+唯一文件名
* @throws IOException IO異常
*/
@PostMapping("/upload")
public String upload(@RequestParam("file") MultipartFile file) throws IOException {
// 1. 空文件校驗(yàn)
if (file.isEmpty()) {
return "上傳失?。何募荒転榭?;
}
// 2. 自動(dòng)創(chuàng)建上傳目錄(不存在則創(chuàng)建)
File directory = new File(uploadDir);
if (!directory.exists()) {
directory.mkdirs();
}
// 3. 生成唯一文件名(防止文件名重復(fù)覆蓋)
String originalFilename = file.getOriginalFilename();
String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
String fileName = UUID.randomUUID() + suffix;
// 4. 構(gòu)建文件最終存儲(chǔ)路徑
File destFile = new File(uploadDir + File.separator + fileName);
// 5. 寫(xiě)入文件到本地
file.transferTo(destFile);
// 返回唯一文件名(前端下載時(shí)需要傳遞此文件名)
return "上傳成功!唯一文件名:" + fileName;
}
/**
* 文件下載接口
* @param fileName 上傳時(shí)返回的唯一文件名
* @param response 響應(yīng)對(duì)象
* @throws IOException IO異常
*/
@GetMapping("/download")
public void download(@RequestParam("fileName") String fileName,
HttpServletResponse response) throws IOException {
// 1. 構(gòu)建文件完整路徑
String filePath = uploadDir + File.separator + fileName;
File file = new File(filePath);
// 2. 文件不存在校驗(yàn)
if (!file.exists()) {
response.getWriter().write("下載失?。何募淮嬖?);
return;
}
// 3. 設(shè)置下載響應(yīng)頭(告訴瀏覽器這是下載文件)
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=" +
URLEncoder.encode(fileName, "UTF-8"));
// 4. 讀取文件流,輸出到前端
try (FileInputStream fis = new FileInputStream(file);
OutputStream os = response.getOutputStream()) {
byte[] buffer = new byte[1024];
int len;
// 循環(huán)讀取文件,寫(xiě)入響應(yīng)流
while ((len = fis.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
os.flush();
}
}
}
四、接口說(shuō)明
- 文件上傳接口
請(qǐng)求地址:http://localhost:8080/file/upload
請(qǐng)求方式:POST
請(qǐng)求參數(shù):file(文件流,前端使用 form-data 格式傳遞)
返回結(jié)果:上傳成功 / 失敗提示 + 唯一文件名
核心特性:
自動(dòng)校驗(yàn)空文件,避免無(wú)效上傳
自動(dòng)創(chuàng)建存儲(chǔ)目錄,無(wú)需手動(dòng)新建文件夾
UUID 生成唯一文件名,解決同名文件覆蓋問(wèn)題 - 文件下載接口
請(qǐng)求地址:http://localhost:8080/file/download
請(qǐng)求方式:GET
請(qǐng)求參數(shù):fileName(上傳接口返回的唯一文件名)
返回結(jié)果:瀏覽器自動(dòng)下載文件
核心特性:
校驗(yàn)文件是否存在,友好提示
解決中文文件名亂碼問(wèn)題
流式輸出,支持大文件下載
五、測(cè)試接口 - 上傳測(cè)試
使用 Postman/Apicap 工具:
請(qǐng)求方式選 POST,地址填 /file/upload
Body 選擇 form-data,key 填 file,類(lèi)型選擇 File
選擇本地文件,點(diǎn)擊發(fā)送,返回成功提示 + 唯一文件名 - 下載測(cè)試
瀏覽器 / 接口工具直接請(qǐng)求:http://localhost:8080/file/download?fileName=上傳返回的唯一文件名
瀏覽器會(huì)自動(dòng)觸發(fā)文件下載
六、注意事項(xiàng)
路徑適配:Windows 系統(tǒng)路徑用 D:/upload,Linux 系統(tǒng)用 /home/upload
文件大小限制:SpringBoot 默認(rèn)文件上傳大小有限制,可在配置文件添加:
yaml
spring:
servlet:
multipart:
max-file-size: 10MB # 單個(gè)文件最大大小
max-request-size: 100MB # 單次請(qǐng)求最大大小
權(quán)限問(wèn)題:Linux 服務(wù)器需確保應(yīng)用對(duì)上傳目錄有讀寫(xiě)權(quán)限
生產(chǎn)環(huán)境:建議搭配 Nginx 做文件訪(fǎng)問(wèn)代理,或使用云存儲(chǔ)(OSS/COS)五、總結(jié)
本文實(shí)現(xiàn)的 SpringBoot 文件上傳下載功能,代碼簡(jiǎn)潔、邏輯完整、無(wú)第三方依賴(lài),非常適合新手學(xué)習(xí)和中小型項(xiàng)目直接使用。核心知識(shí)點(diǎn):
- MultipartFile 處理文件上傳
- UUID 防止文件名重復(fù)
- 響應(yīng)流實(shí)現(xiàn)文件下載
- 基礎(chǔ)校驗(yàn)提升接口健壯性
到此這篇關(guān)于SpringBoot實(shí)現(xiàn)文件上傳與下載功能的詳細(xì)教程的文章就介紹到這了,更多相關(guān)SpringBoot文件上傳與下載內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在Mybatis中association標(biāo)簽多層嵌套的問(wèn)題
這篇文章主要介紹了在Mybatis中association標(biāo)簽多層嵌套的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
Spring循環(huán)依賴(lài)的三種方式(推薦)
本篇文章主要介紹了Spring循環(huán)依賴(lài)的三種方式,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-01-01
java實(shí)現(xiàn)讀取jar包中配置文件的幾種方式
本文主要介紹了java實(shí)現(xiàn)讀取jar包中配置文件的幾種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06
spring cloud 使用Eureka 進(jìn)行服務(wù)治理方法
這篇文章主要介紹了spring cloud 使用Eureka 進(jìn)行服務(wù)治理方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-05-05
SpringBoot實(shí)現(xiàn)分布式驗(yàn)證碼登錄方案小結(jié)
驗(yàn)證碼登錄作為一種有效的防護(hù)手段,可以防止惡意gongji、暴力pojie等,本文主要介紹了SpringBoot實(shí)現(xiàn)分布式驗(yàn)證碼登錄方案小結(jié),具有一定的參考價(jià)值,感興趣的可以了解一下2024-12-12
JAVA實(shí)現(xiàn)Token自動(dòng)續(xù)期機(jī)制的示例代碼
本文主要介紹了JAVA實(shí)現(xiàn)Token自動(dòng)續(xù)期機(jī)制的示例代碼,通過(guò)動(dòng)態(tài)調(diào)整會(huì)話(huà)生命周期平衡安全性與用戶(hù)體驗(yàn),解決固定有效期Token帶來(lái)的風(fēng)險(xiǎn)與不便,感興趣的可以了解一下2025-09-09
基于Springboot+Junit+Mockito做單元測(cè)試的示例
本篇文章主要介紹了基于Springboot+Junit+Mockito做單元測(cè)試的示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-02-02

