大家好,我是小富~
又是做好人好事的一天,有個小可愛私下問我有沒有好用的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
總結
用了這個工具確實極大的減少了上傳文件所帶來的代碼量,提升了開發效率,使用過程中暫未發現有什麼坑,好東西就是要大家分享,如果符合你的需求,猶豫什麼用起來吧。
技術交流,公衆號:程序員小富