大家好,我是小富~
又是做好人好事的一天,有個小可愛私下問我有沒有好用的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: "http://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: http://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("http://file.abc.com/test/a.jpg");
// 下載到檔案
fileStorageService.download(fileInfo).file("C:\\a.jpg");
// 直接通過檔案資訊中的 url 下載,省去手動查詢檔案資訊記錄的過程
fileStorageService.download("http://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("http://file.abc.com/test/a.jpg");
//直接通過檔案資訊中的 url 判斷檔案是否存在,省去手動查詢檔案資訊記錄的過程
boolean exists2 = fileStorageService.exists("http://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案例地址:https://github.com/chengxy-nds/Springboot-Notebook/tree/master/springboot-file-storage
用了這個工具確實極大的減少了上傳檔案所帶來的程式碼量,提升了開發效率,使用過程中暫未發現有什麼坑,好東西就是要大家分享,如果符合你的需求,猶豫什麼用起來吧。
技術交流,公眾號:程式設計師小富