大家好登疗,我是小富~
技術(shù)交流,公眾號(hào):程序員小富
又是做好人好事的一天嫌蚤,有個(gè)小可愛私下問我有沒有好用的springboot
文件上傳工具辐益,這不巧了嘛,正好我私藏了一個(gè)好東西脱吱,順便給小伙伴們也分享一下智政,demo地址放在文末了。
[圖片上傳失敗...(image-22eaf9-1666669368274)]
文件上傳在平常不過的一個(gè)功能箱蝠,做后端開發(fā)的基本都會(huì)接觸到续捂,雖然不難可著實(shí)有點(diǎn)繁瑣。數(shù)據(jù)流的開閉宦搬、讀取還容易出錯(cuò)牙瓢,尤其是在對(duì)接一些OSS
對(duì)象存儲(chǔ)平臺(tái),一個(gè)平臺(tái)一堆SDK代碼看起來亂糟糟的间校。
下邊給我大家推薦一個(gè)工具Spring File Storage
矾克,上傳文件只要些許配置一行代碼搞定,開發(fā)效率杠杠的撇簿,一起看看是不是有這么流批聂渊!
Spring File Storage
工具幾乎整合了市面上所有的OSS對(duì)象存儲(chǔ)平臺(tái),包括本地
四瘫、FTP
汉嗽、SFTP
、WebDAV
找蜜、阿里云OSS
饼暑、華為云OBS
、七牛云Kodo
洗做、騰訊云COS
弓叛、百度云 BOS
、又拍云USS
诚纸、MinIO
撰筷、京東云 OSS
、網(wǎng)易數(shù)帆 NOS
等其它兼容 S3 協(xié)議的平臺(tái)畦徘,只要在springboot中通過極簡(jiǎn)的方式就可以實(shí)現(xiàn)文件存儲(chǔ)毕籽。
[圖片上傳失敗...(image-aa4d74-1666669368274)]
簡(jiǎn)單配置
下邊以本地和Aliyun OSS上傳為例抬闯,pom.xml
中引入必要的spring-file-storage.jar
,注意: 如果要上傳文件到OSS平臺(tái)关筒,需要引入對(duì)應(yīng)平臺(tái)的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
文件中配置些基礎(chǔ)信息。
-
enable-storage
:只有狀態(tài)開啟才會(huì)被識(shí)別到 -
default-platform
:默認(rèn)的上傳平臺(tái) -
domain
:生成的文件url中訪問的域名 -
base-path
:存儲(chǔ)地址 -
thumbnail-suffix
:縮略圖后綴
要是上傳OSS對(duì)象存儲(chǔ)平臺(tái)蒸播,將aliyun oss
提供的變量配置到相應(yīng)的模塊上即可睡榆。
spring:
#文件存儲(chǔ)配置(本地、oss)
file-storage:
default-platform: local-1
thumbnail-suffix: ".min.jpg" #縮略圖后綴
local:
- platform: local-1 # 存儲(chǔ)平臺(tái)標(biāo)識(shí)
enable-storage: true #是否開啟本存儲(chǔ)(只能選一種)
enable-access: true #啟用訪問(線上請(qǐng)使用 Nginx 配置袍榆,效率更高)
domain: "http://127.0.0.1:2222" #訪問域名胀屿,注意后面要和path-patterns保持一致,“/”結(jié)尾
base-path: /tmp/Pictures/ # 存儲(chǔ)地址
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: #云平臺(tái)文件路徑
springboot
啟動(dòng)類中增加注解@EnableFileStorage
包雀,顯式的開啟文件上傳功能碉纳,到這就可以用了
@EnableFileStorage // 文件上傳工具
@SpringBootApplication
public class SpringbootFileStorageApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootFileStorageApplication.class, args);
}
}
上傳文件
接下來在業(yè)務(wù)類中引入FileStorageService
服務(wù),如下只要一行代碼就可以完成文件上傳馏艾,是不是So easy劳曹,下載也是如法炮制。
@RestController
public class FileController {
@Autowired
private FileStorageService fileStorageService;
/**
* 公眾號(hào):程序員小富
* 上傳文件
*/
@PostMapping(value = {"/upload"})
public Object upload(MultipartFile file) {
FileInfo upload = fileStorageService.of(file).upload();
return upload;
}
}
我們用postman
測(cè)試上傳一張圖片琅摩,看到圖片已經(jīng)成功傳到了/tmp/Pictures
目錄下铁孵,返回結(jié)果中包含了完整的訪問文件的URL路徑。
[圖片上傳失敗...(image-8466da-1666669368274)]
[圖片上傳失敗...(image-4c0e9c-1666669368274)]
不僅如此spring-file-storage
還支持多種文件形式房资,URI
蜕劝、URL
、String
轰异、byte[]
岖沛、InputStream
、MultipartFile
搭独,使開發(fā)更加靈活婴削。
[圖片上傳失敗...(image-f0fb9-1666669368274)]
文件上傳功能,更多時(shí)候我們都是在上傳圖片牙肝,那就會(huì)有動(dòng)態(tài)裁剪圖片
唉俗、生成縮略圖
的需求,這些 spring-file-storage 都可以很容易實(shí)現(xiàn)配椭。
/**
* 公眾號(hào):程序員小富
* 上傳圖片裁剪大小并生成一張縮略圖
*/
@PostMapping("/uploadThumbnail")
public FileInfo uploadThumbnail(MultipartFile file) {
return fileStorageService.of(file)
.image(img -> img.size(1000,1000)) //將圖片大小調(diào)整到 1000*1000
.thumbnail(th -> th.size(200,200)) //再生成一張 200*200 的縮略圖
.upload();
}
而且我們還可以動(dòng)態(tài)選擇上傳平臺(tái)虫溜,配置文件中將所有平臺(tái)開啟,在實(shí)際使用中自由的選擇股缸。
/**
* 公眾號(hào):程序員小富
* 上傳文件到指定存儲(chǔ)平臺(tái)衡楞,成功返回文件信息
*/
@PostMapping("/upload-platform")
public FileInfo uploadPlatform(MultipartFile file) {
return fileStorageService.of(file)
.setPlatform("aliyun-oss") //使用指定的存儲(chǔ)平臺(tái)
.upload();
}
下載文件
下載文件也同樣的簡(jiǎn)單,可以直接根據(jù)文件url或者文件流下載敦姻。
/**
* 公眾號(hào):程序員小富
* 下載文件
*/
@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 下載瘾境,省去手動(dòng)查詢文件信息記錄的過程
fileStorageService.download("http://file.abc.com/test/a.jpg").file("C:\\a.jpg");
// 下載縮略圖
fileStorageService.downloadTh(fileInfo).file("C:\\th.jpg");
}
提供了監(jiān)聽下載進(jìn)度的功能坎背,可以清晰明了的掌握文件的下載情況。
// 下載文件 顯示進(jìn)度
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("下載結(jié)束");
}
}).file("C:\\a.jpg");
文件存在寄雀、刪除
我們還可以根據(jù)文件的URL地址來判斷文件是否存在、以及刪除文件陨献。
//直接通過文件信息中的 url 刪除盒犹,省去手動(dòng)查詢文件信息記錄的過程
fileStorageService.delete("http://file.abc.com/test/a.jpg");
//直接通過文件信息中的 url 判斷文件是否存在,省去手動(dòng)查詢文件信息記錄的過程
boolean exists2 = fileStorageService.exists("http://file.abc.com/test/a.jpg");
切面
工具還提供了每種操作的切面眨业,可以在每個(gè)動(dòng)作的前后進(jìn)行干預(yù)急膀,比如打日志或者玩點(diǎn)花活,實(shí)現(xiàn)FileStorageAspect
類重寫對(duì)應(yīng)動(dòng)作的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
總結(jié)
用了這個(gè)工具確實(shí)極大的減少了上傳文件所帶來的代碼量聘殖,提升了開發(fā)效率晨雳,使用過程中暫未發(fā)現(xiàn)有什么坑,好東西就是要大家分享奸腺,如果符合你的需求餐禁,猶豫什么用起來吧。
技術(shù)交流突照,公眾號(hào):程序員小富