基于SpringBoot框架實(shí)現(xiàn)文件上傳下載分享功能
SpringBoot 文件上傳下載是我們常用的功能,比如圖片、視頻上傳、下載和更新等功能的實(shí)現(xiàn)。下面我們?cè)敿?xì)分析一下:
1、pom.xml包引入
<!-- 基礎(chǔ) web 依賴(包含文件上傳支持) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 文件操作工具類 -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>2、存儲(chǔ)目錄設(shè)計(jì)
/data/project_files/
├── images/
│ ├── 202405/
│ └── 202406/
└── videos/
├── 202405/
└── 202406/- 使用 UUID 生成唯一文件名(保留原始擴(kuò)展名)
- 按年月生成子目錄(防止單目錄文件過多)
- 推薦存儲(chǔ)絕對(duì)路徑到數(shù)據(jù)庫(如:/images/202405/uuid123.jpg)
3、配置文件信息
# win環(huán)境文件存儲(chǔ)根目錄 file.upload-dir=D:/data/project_files/ #linux環(huán)境 file.upload-dir=/data/project_files/ # 上傳大小限制(默認(rèn)1MB,按需調(diào)整) spring.servlet.multipart.max-file-size=100MB spring.servlet.multipart.max-request-size=100MB
4、上傳接口
@PostMapping("/upload")
public ApiResult uploadFile(@RequestParam("file") MultipartFile file,
@RequestParam String fileType) throws IOException {
// 驗(yàn)證文件類型
if (!Arrays.asList("image", "video").contains(fileType)) {
return ApiResult.error("Invalid file type");
}
// 生成存儲(chǔ)路徑
String datePath = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMM"));
String fileExt = FilenameUtils.getExtension(file.getOriginalFilename());
String uuid = UUID.randomUUID().toString();
String relativePath = String.format("/%s/%s/%s.%s",
fileType + "s", datePath, uuid, fileExt);
// 保存文件
File dest = new File(uploadDir + relativePath);
FileUtils.forceMkdirParent(dest);
file.transferTo(dest);
return ApiResult.ok(relativePath);
}直接獲取下載地址上傳方式
@PostMapping("/uploadFile")
@ApiOperation(value="文件上傳",notes = "文件上傳-√")
public String uploadFile(@RequestParam("file")MultipartFile file, @RequestParam String fileType) throws IOException {
// 驗(yàn)證文件類型
if (!Arrays.asList("image", "video").contains(fileType)) {
return CommonResponse.buildErrorResponse("Error file type");
}
// 生成存儲(chǔ)路徑
String datePath = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMM"));
String fileExt = FilenameUtils.getExtension(file.getOriginalFilename());
String uuid = UUID.randomUUID().toString();
String relativePath = String.format("/%s/%s/%s.%s",
fileType + "s", datePath, uuid, fileExt);
// 保存文件
File dest = new File(uploadDir + relativePath);
FileUtils.forceMkdirParent(dest);
file.transferTo(dest);
log.info("filePath:{}",fileIpPortUrl+relativePath);
return (fileIpPortUrl+relativePath);
}5、下載接口
1)接口下載
@GetMapping("/download")
public ResponseEntity<Resource> downloadFile(@RequestParam String filePath) throws IOException {
Path path = Paths.get(uploadDir + filePath);
Resource resource = new UrlResource(path.toUri());
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + resource.getFilename() + "\"")
.body(resource);
}2)原路徑獲取下載
@GetMapping("/download/**")
@ApiOperation(value="文件下載接口",notes = "文件下載接口-√")
public ResponseEntity<Resource> downloadFile(HttpServletRequest request) throws IOException {
// 獲取完整文件路徑(需截掉前綴路徑)
String filePath = request.getServletPath()
.replaceFirst("/file/******/", "");
log.info("filePath:{}",filePath);
// 路徑安全校驗(yàn)
if (filePath.contains("..")) {
return ResponseEntity.badRequest().build();
}
Path path = Paths.get(uploadDir + File.separator + filePath);
log.info("path:{}",path);
Resource resource = new UrlResource(path.toUri());
log.info("toUri:{}",path.toUri());
if (!resource.exists()) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + resource.getFilename() + "\"")
.body(resource);
}6、修改文件
@PostMapping("/update")
public ApiResult updateFile(@RequestParam("file") MultipartFile file,
@RequestParam String oldFilePath) throws IOException {
// 刪除舊文件
File oldFile = new File(uploadDir + oldFilePath);
if (oldFile.exists()) {
FileUtils.forceDelete(oldFile);
}
// 上傳新文件(復(fù)用上傳邏輯)
return uploadFile(file, parseFileType(oldFilePath));
}或者
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.UUID;
@PostMapping("/update")
public String updateFile(@RequestParam("file") MultipartFile file,
@RequestParam String oldFilePath, @RequestParam String fileType) throws IOException {
// 刪除舊文件
File oldFile = new File(uploadDir + oldFilePath);
if (oldFile.exists()) {
FileUtils.forceDelete(oldFile);
}
// 上傳新文件(復(fù)用上傳邏輯)
return uploadFile(file, fileType);
}到此,文件上傳下載分享完成。
到此這篇關(guān)于基于SpringBoot框架實(shí)現(xiàn)文件上傳下載分享功能的文章就介紹到這了,更多相關(guān)SpringBoot文件上傳下載分享內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring Security使用數(shù)據(jù)庫認(rèn)證及用戶密碼加密和解密功能
這篇文章主要介紹了Spring Security使用數(shù)據(jù)庫認(rèn)證及用戶密碼加密和解密,本文通過代碼與截圖的形式給大家介紹的非常詳細(xì),對(duì)大家的工作或?qū)W習(xí)具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03
SpringBoot自動(dòng)配置@EnableAutoConfiguration過程示例
這篇文章主要為大家介紹了SpringBoot自動(dòng)配置@EnableAutoConfiguration的過程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10
SpringBoot中實(shí)現(xiàn)JSON轉(zhuǎn)Word格式的示例詳解
這篇文章主要為大家詳細(xì)介紹了如何使用SpringBoot實(shí)現(xiàn)JSON轉(zhuǎn)Word格式,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-05-05
Maven基礎(chǔ)之如何修改本地倉庫的默認(rèn)路徑
這篇文章主要介紹了Maven基礎(chǔ)之如何修改本地倉庫的默認(rèn)路徑問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05
Java使用FileReader.read()讀取文件時(shí)亂碼的兩個(gè)解決方案
文章主要討論了在Java中使用FileReader讀取文件時(shí)可能出現(xiàn)的亂碼問題,并提出了通過指定文件編碼格式和使用int類型接收讀取到的字節(jié)來解決亂碼的方法2026-01-01
jenkins-jdk8.0環(huán)境準(zhǔn)備及部署過程
這篇文章主要介紹了jenkins-jdk8.0環(huán)境準(zhǔn)備及部署過程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2025-05-05
Redisson延遲隊(duì)列實(shí)現(xiàn)訂單關(guān)閉的操作方法
Redisson的RDelayedQueue是實(shí)現(xiàn)訂單到期關(guān)閉的利器,它比定時(shí)任務(wù)更精準(zhǔn)、比Redis過期監(jiān)聽更可靠,下面一步步給大家介紹Redisson延遲隊(duì)列實(shí)現(xiàn)訂單關(guān)閉功能,感興趣的朋友一起看看吧2026-03-03

