Springboot一行代码实现文件上传20个平台!少写代码到极致
大家好,我是小富~
又是做好人好事的一天,有个小可爱私下问我有没有好用的 springboot 文件上传工具,这不巧了嘛,正好我私藏了一个好东西,顺便给小伙伴们也分享一下,demo 地址放在文末了。
文件上传在平常不过的一个功能,做后端开发的基本都会接触到,虽然不难可着实有点繁琐。数据流的开闭、读取还容易出错,尤其是在对接一些 OSS 对象存储平台,一个平台一堆SDK代码看起来乱糟糟的。
下边给我大家推荐一个工具 Spring File Storage ,上传文件只要些许配置一行代码 搞定,开发效率杠杠的,一起看看是不是有这么流批! "
官网:https://spring-file-storage.xuyanwu.cn
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包。 cn.xuyanwu spring-file-storage 0.5.0 com.aliyun.oss aliyun-sdk-oss 3.10.2
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 总结
用了这个工具确实极大的减少了上传文件所带来的代码量,提升了开发效率,使用过程中暂未发现有什么坑,好东西就是要大家分享,如果符合你的需求,犹豫什么用起来吧。
我是小富,下期见~
全网搜:程序员小富。
整理了几百本各类技术电子书,有需要的同学可以,私信或者评论【666】 自取。还有想要加技术群的同学可以加我好友,和大佬侃技术、不定期内推,程序员的内点事这都有。
8星界龙3冒险家2龙神,龙王大哥索尔带上小弟呲呲收割人头金铲铲新版本隐秘之海更新后,大家玩了一阵子后研究出来的新手阵容实在是太多了,玩法多样,阵容齐出。不管怎么说,能上分的阵容都是好阵容,你们觉得呢?下面给大家推荐一款玩星界龙顶配的阵容
一拳超人正义执行战栗的龙卷是谁一拳超人正义执行战栗的龙卷简介战栗的龙卷属于一拳超人正义执行游戏中的攻击角色,具有超高的群体伤害,能给玩家带来流畅的战斗过程。现在,我将从多个方面向你介绍这个角色,让你更好地了解她。拳击超人正义处决战栗的龙卷游
B站独播TI11RNG表现满分,VG打了一手好牌,这是最有希望的一年提到TI11,想必不少玩家脑海里会浮现RNG的身影,要知道他们在这次的比赛中表现非常亮眼,甚至有玩家表示,今年冠军就靠他们了,无论是国内赛还是预选赛,展现出那种想要获得胜利的欲望都
心越美,命越好蒋勋老师曾说,你看到了美,才会觉得世界美,而所有的美都需要你花时间与精力。是的,如果我们只是走马观花,那么到最后,我们看过的风景与人事,不过是模糊的印记而已。01hr只有用心,才看
品风(原创)树叶泛黄,北风呼啸,寒气飞扬,刮着脸庞,痛在心上。秋已过去,该添衣裳,没想叶落,好把心伤点滴甜蜜,永刻心房。如今游离,不晓怎样?此时尽管有满腹的美味,全仰蜂忙!季节的交换,实属不愿
几时归去?做个闲人,青山结庐,白发归隐长假,前三日还是盛夏的样子,可是4号以后,气温却暴跌二十度,一夜之间,宛如两个季节。晚上散步,发现不知不觉秋意已浓了,这样凉意袭人的深秋夜晚十分喜欢。今早出去买菜,看到路边不知第几
世上最疼的病是什么病?临床上这5种疼痛,经历过的都是超人刚进科室,我就看见有一对母女急匆匆地跑进来,张女士显得有些焦虑,而她的母亲更是满头大汗,我没有着急问情况,等她们俩情绪平静我才开始询问病情。原来29岁的张女士在2年前生下一个孩子,
没想到国少队踢这么好,超出所有人预期开场的一次连续的各个位置的失误,让我有点紧张。从前场直至后防线的连续失误,真的让我有点紧张。此时,转播信号戛然而止,十来分钟的等待,时间好像过得很慢。信号来了,好像也没有获得大多优
湖人战森林狼三巨头缺席,浓眉又受伤!哈姆练兵,2人值得重用前言本以为与太阳的比赛可以稳稳拿下,在领先三节之后,湖人还是在末节崩盘。几乎领先两位数的情况下,被太阳一波小高潮带走。当然,和上场失利情况一样,湖人主帅哈姆并没有为了胜利而让主力球
大傻春,你要干嘛追梦在训练中打了普尔,可谓意外又不意外的新闻意外的是,竟然有人在训练中打队友不意外的是,打人者是合同年的追梦?噢,那没事了。这件事最妙的是,它出现的时间点。近期有两个关键事件,一个
欧冠皇马21矿工取得三连胜!罗德里戈维尼修斯各入一球北京时间10月6日凌晨3点,欧冠小组赛第3轮,皇家马德里主场对阵顿涅茨克矿工。前两轮,皇马30胜凯尔特人,20胜莱比锡,取得两连胜。矿工41莱比锡,11凯尔特人,排在小组第二。开场