Springboot 一行程式碼實現文件上傳 20個平台!少寫程式碼到極致
- 2022 年 10 月 25 日
- 筆記
- Java開發, springboot, 後端, 程式設計師
大家好,我是小富~
又是做好人好事的一天,有個小可愛私下問我有沒有好用的springboot
文件上傳工具,這不巧了嘛,正好我私藏了一個好東西,順便給小夥伴們也分享一下,demo地址放在文末了。
文件上傳在平常不過的一個功能,做後端開發的基本都會接觸到,雖然不難可著實有點繁瑣。數據流的開閉、讀取還容易出錯,尤其是在對接一些OSS
對象存儲平台,一個平台一堆SDK程式碼看起來亂糟糟的。
下邊給我大家推薦一個工具Spring File Storage
,上傳文件只要些許配置一行程式碼搞定,開發效率杠杠的,一起看看是不是有這麼流批!
Spring File Storage
工具幾乎整合了市面上所有的OSS對象存儲平台,包括本地
、FTP
、SFTP
、WebDAV
、阿里雲OSS
、華為雲OBS
、七牛雲Kodo
、騰訊雲COS
、百度雲 BOS
、又拍雲USS
、MinIO
、京東雲 OSS
、網易數帆 NOS
等其它兼容 S3 協議的平台,只要在springboot中通過極簡的方式就可以實現文件存儲。
簡單配置
下邊以本地和Aliyun OSS上傳為例,pom.xml
中引入必要的spring-file-storage.jar
,注意: 如果要上傳文件到OSS平台,需要引入對應平台的SDK包。
<!-- spring-file-storage 必須要引入 -->
<dependency>
<groupId>cn.xuyanwu</groupId>
<artifactId>spring-file-storage</artifactId>
<version>0.5.0</version>
</dependency>
<!-- 阿里雲oss -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.10.2</version>
</dependency>
application.yml
文件中配置些基礎資訊。
enable-storage
:只有狀態開啟才會被識別到default-platform
:默認的上傳平台domain
:生成的文件url中訪問的域名base-path
:存儲地址thumbnail-suffix
:縮略圖後綴
要是上傳OSS對象存儲平台,將aliyun oss
提供的變數配置到相應的模組上即可。
spring:
#文件存儲配置(本地、oss)
file-storage:
default-platform: local-1
thumbnail-suffix: ".min.jpg" #縮略圖後綴
local:
- platform: local-1 # 存儲平台標識
enable-storage: true #是否開啟本存儲(只能選一種)
enable-access: true #啟用訪問(線上請使用 Nginx 配置,效率更高)
domain: "//127.0.0.1:2222" #訪問域名,注意後面要和path-patterns保持一致,「/」結尾
base-path: /tmp/Pictures/ # 存儲地址
path-patterns: /** #訪問路徑
aliyun-oss:
- platform: aliyun-oss
enable-storage: true
access-key: xxxx
secret-key: xxxx
end-point: xxx
bucket-name: firebook
domain: //fire100.top
base-path: #雲平台文件路徑
springboot
啟動類中增加註解@EnableFileStorage
,顯式的開啟文件上傳功能,到這就可以用了
@EnableFileStorage // 文件上傳工具
@SpringBootApplication
public class SpringbootFileStorageApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootFileStorageApplication.class, args);
}
}
上傳文件
接下來在業務類中引入FileStorageService
服務,如下只要一行程式碼就可以完成文件上傳,是不是So easy,下載也是如法炮製。
@RestController
public class FileController {
@Autowired
private FileStorageService fileStorageService;
/**
* 公眾號:程式設計師小富
* 上傳文件
*/
@PostMapping(value = {"/upload"})
public Object upload(MultipartFile file) {
FileInfo upload = fileStorageService.of(file).upload();
return upload;
}
}
我們用postman
測試上傳一張圖片,看到圖片已經成功傳到了/tmp/Pictures
目錄下,返回結果中包含了完整的訪問文件的URL路徑。
不僅如此spring-file-storage
還支援多種文件形式,URI
、URL
、String
、byte[]
、InputStream
、MultipartFile
,使開發更加靈活。
文件上傳功能,更多時候我們都是在上傳圖片,那就會有動態裁剪圖片
、生成縮略圖
的需求,這些 spring-file-storage 都可以很容易實現。
/**
* 公眾號:程式設計師小富
* 上傳圖片裁剪大小並生成一張縮略圖
*/
@PostMapping("/uploadThumbnail")
public FileInfo uploadThumbnail(MultipartFile file) {
return fileStorageService.of(file)
.image(img -> img.size(1000,1000)) //將圖片大小調整到 1000*1000
.thumbnail(th -> th.size(200,200)) //再生成一張 200*200 的縮略圖
.upload();
}
而且我們還可以動態選擇上傳平台,配置文件中將所有平台開啟,在實際使用中自由的選擇。
/**
* 公眾號:程式設計師小富
* 上傳文件到指定存儲平台,成功返迴文件資訊
*/
@PostMapping("/upload-platform")
public FileInfo uploadPlatform(MultipartFile file) {
return fileStorageService.of(file)
.setPlatform("aliyun-oss") //使用指定的存儲平台
.upload();
}
下載文件
下載文件也同樣的簡單,可以直接根據文件url或者文件流下載。
/**
* 公眾號:程式設計師小富
* 下載文件
*/
@PostMapping("/download")
public void download(MultipartFile file) {
// 獲取文件資訊
FileInfo fileInfo = fileStorageService.getFileInfoByUrl("//file.abc.com/test/a.jpg");
// 下載到文件
fileStorageService.download(fileInfo).file("C:\\a.jpg");
// 直接通過文件資訊中的 url 下載,省去手動查詢文件資訊記錄的過程
fileStorageService.download("//file.abc.com/test/a.jpg").file("C:\\a.jpg");
// 下載縮略圖
fileStorageService.downloadTh(fileInfo).file("C:\\th.jpg");
}
提供了監聽下載進度的功能,可以清晰明了的掌握文件的下載情況。
// 下載文件 顯示進度
fileStorageService.download(fileInfo).setProgressMonitor(new ProgressListener() {
@Override
public void start() {
System.out.println("下載開始");
}
@Override
public void progress(long progressSize,long allSize) {
System.out.println("已下載 " + progressSize + " 總大小" + allSize);
}
@Override
public void finish() {
System.out.println("下載結束");
}
}).file("C:\\a.jpg");
文件存在、刪除
我們還可以根據文件的URL地址來判斷文件是否存在、以及刪除文件。
//直接通過文件資訊中的 url 刪除,省去手動查詢文件資訊記錄的過程
fileStorageService.delete("//file.abc.com/test/a.jpg");
//直接通過文件資訊中的 url 判斷文件是否存在,省去手動查詢文件資訊記錄的過程
boolean exists2 = fileStorageService.exists("//file.abc.com/test/a.jpg");
切面
工具還提供了每種操作的切面,可以在每個動作的前後進行干預,比如打日誌或者玩點花活,實現FileStorageAspect
類重寫對應動作的xxxAround方法。
**
* 使用切面列印文件上傳和刪除的日誌
*/
@Slf4j
@Component
public class LogFileStorageAspect implements FileStorageAspect {
/**
* 上傳,成功返迴文件資訊,失敗返回 null
*/
@Override
public FileInfo uploadAround(UploadAspectChain chain, FileInfo fileInfo, UploadPretreatment pre, FileStorage fileStorage, FileRecorder fileRecorder) {
log.info("上傳文件 before -> {}",fileInfo);
fileInfo = chain.next(fileInfo,pre,fileStorage,fileRecorder);
log.info("上傳文件 after -> {}",fileInfo);
return fileInfo;
}
}
demo案例地址://github.com/chengxy-nds/Springboot-Notebook/tree/master/springboot-file-storage
總結
用了這個工具確實極大的減少了上傳文件所帶來的程式碼量,提升了開發效率,使用過程中暫未發現有什麼坑,好東西就是要大家分享,如果符合你的需求,猶豫什麼用起來吧。
技術交流,公眾號:程式設計師小富