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
总结
用了这个工具确实极大的减少了上传文件所带来的代码量,提升了开发效率,使用过程中暂未发现有什么坑,好东西就是要大家分享,如果符合你的需求,犹豫什么用起来吧。
技术交流,公众号:程序员小富