Spring File Storage(文件的对象存储)框架基本使用指南

概述

本文仅作为快速入门,深入学习及使用详见官网

云存储

在开发过程当中,会使用到存文档、图片、视频、音频等等,这些都会涉及存储的问题,文件可以直接存服务器,但需要考虑带宽和存储空间,另外一种方式就是使用云存储。目前主流的云存储有阿里云OSS、华为云OBS、七牛云Kodo、腾讯云COS、百度云 BOS、又拍云USS、MinIO 等。

X Spring File Storage 介绍

在 SpringBoot 中通过简单的方式将文件存储到 本地、FTP、SFTP、WebDAV、谷歌云存储、阿里云OSS、华为云OBS、七牛云Kodo、腾讯云COS、百度云 BOS、又拍云USS、MinIO、 AWS S3、金山云 KS3、美团云 MSS、京东云 OSS、天翼云 OOS、移动云 EOS、沃云 OSS、 网易数帆 NOS、Ucloud US3、青云 QingStor、平安云 OBS、首云 OSS、IBM COS、其它兼容 S3 协议的平台。

支持的平台如下图:

在这里插入图片描述


快速入门

添加依赖

<dependencies><!-- spring-file-storage 必须要引入 --><dependency><groupId>cn.xuyanwu</groupId><artifactId>spring-file-storage</artifactId><version>2.1.0</version></dependency><!-- 华为云OBS 不使用的情况下可以不引入 --><dependency><groupId>com.huaweicloud</groupId><artifactId>esdk-obs-java</artifactId><version>3.22.12</version></dependency><!-- 阿里云OSS 不使用的情况下可以不引入 --><dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.16.1</version></dependency>

添加配置文件

注:以下配置是 2.1.0 版本的配置

dromara:x-file-storage: #文件存储配置default-platform: huawei-obs-1 #默认使用的存储平台thumbnail-suffix: ".min.jpg" #缩略图后缀,例如【.min.jpg】【.png】# 对应平台的配置写在这里,注意缩进要对齐huawei-obs:- platform: huawei-obs-1 # 存储平台标识enable-storage: true  # 启用存储。只有状态开启才会被识别到access-key: ??secret-key: ??end-point: ??bucket-name: ??domain: ?? # 访问域名,注意“/”结尾,例如:http://abc.obs.com/base-path: test/ # 基础路径# 本地存储(升级版)local-plus:- platform: local-plus-1 # 存储平台标识enable-storage: true  #启用存储enable-access: true #启用访问(线上请使用 Nginx 配置,效率更高)domain: http://127.0.0.1:8080/file/ # 访问域名,例如:“http://127.0.0.1:8030/file/”,注意后面要和 path-patterns 保持一致,“/”结尾,本地存储建议使用相对路径,方便后期更换域名base-path: local-plus/ # 基础路径path-patterns: /file/** # 访问路径storage-path: D:/Temp/ # 存储路径

编码

显式的开启文件上传功能

在启动类上加上@EnableFileStorage注解

@EnableFileStorage
@SpringBootApplication
public class SpringFileStorageTestApplication {public static void main(String[] args) {SpringApplication.run(SpringFileStorageTestApplication.class,args);}}

上传

支持 File、MultipartFile、byte[]、InputStream、URL、URI、String、HttpServletRequest,大文件会自动分片上传。

@RestController
public class FileDetailController {@Autowiredprivate FileStorageService fileStorageService;//注入实列/*** 上传文件*/@PostMapping("/upload")public FileInfo upload(MultipartFile file) {return fileStorageService.of(file).upload();}/*** 上传文件,成功返回文件 url*/@PostMapping("/upload2")public String upload2(MultipartFile file) {FileInfo fileInfo = fileStorageService.of(file).setPath("upload/") //保存到相对路径下,为了方便管理,不需要可以不写.setObjectId("0")   //关联对象id,为了方便管理,不需要可以不写.setObjectType("0") //关联对象类型,为了方便管理,不需要可以不写.putAttr("role","admin") //保存一些属性,可以在切面、保存上传记录、自定义存储平台等地方获取使用,不需要可以不写.upload();  //将文件上传到对应地方return fileInfo == null ? "上传失败!" : fileInfo.getUrl();}/*** 上传图片,成功返回文件信息* 图片处理使用的是 https://github.com/coobird/thumbnailator*/@PostMapping("/upload-image")public FileInfo uploadImage(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-1")    //使用指定的存储平台.upload();}/*** 直接读取 HttpServletRequest 中的文件进行上传,成功返回文件信息* 使用这种方式有些注意事项,请查看文档 基础功能-上传 章节*/@PostMapping("/upload-request")public FileInfo uploadPlatform(HttpServletRequest request) {return fileStorageService.of(request).upload();}
}

文件是否存在、下载、删除

//手动构造文件信息,可用于其它操作
FileInfo fileInfo = new FileInfo().setPlatform("huawei-obs-1").setBasePath("test/").setPath("aa/").setFilename("image.png").setThFilename("image.png.min.jpg");
//文件是否存在
boolean exists = fileStorageService.exists(fileInfo);
//下载
byte[] bytes = fileStorageService.download(fileInfo).bytes();
// 下载到文件
fileStorageService.download(fileInfo).file("C:\\a.jpg");
// 下载缩略图
fileStorageService.downloadTh(fileInfo).file("C:\\th.jpg");
//删除
fileStorageService.delete(fileInfo);// 如果将文件记录保存到数据库中,还可以更方便的根据 URL 进行操作
//直接从数据库中获取 FileInfo 对象,更加方便执行其它操作
FileInfo fileInfo = fileStorageService.getFileInfoByUrl("https://abc.def.com/test/aa/image.png");
//文件是否存在
boolean exists = fileStorageService.exists("https://abc.def.com/test/aa/image.png");
//下载
byte[] bytes = fileStorageService.download("https://abc.def.com/test/aa/image.png").bytes();
//删除
fileStorageService.delete("https://abc.def.com/test/aa/image.png");

监听器

// 下载文件 显示进度
fileStorageService.download(fileInfo).setProgressMonitor(new ProgressListener() {@Overridepublic void start() {System.out.println("下载开始");}@Overridepublic void progress(long progressSize,long allSize) {System.out.println("已下载 " + progressSize + " 总大小" + allSize);}@Overridepublic void finish() {System.out.println("下载结束");}
}).file("C:\\a.jpg");

切面

工具还提供了每种操作的切面,可以在每个动作的前后进行干预,比如打日志,实现 FileStorageAspect 类重写对应动作的 xxxAround 方法。

/*** 使用切面打印文件上传和删除的日志*/
@Slf4j
@Component
public class LogFileStorageAspect implements FileStorageAspect {/*** 上传,成功返回文件信息,失败返回 null*/@Overridepublic 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;}
}

表设计

-- mysql
DROP TABLE IF EXISTS `file_detail`;
CREATE TABLE `file_detail`
(`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '文件id',`url` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '文件访问地址',`size`  bigint(20) NULL DEFAULT NULL COMMENT '文件大小,单位字节',`filename` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '文件名称',`original_filename` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '原始文件名',`base_path` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '基础存储路径',`path` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '存储路径',`ext` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci  NULL DEFAULT NULL COMMENT '文件扩展名',`content_type` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'MIME类型',`platform` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci  NULL DEFAULT NULL COMMENT '存储平台',`th_url` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '缩略图访问路径',`th_filename` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '缩略图名称',`th_size` bigint(20) NULL DEFAULT NULL COMMENT '缩略图大小,单位字节',`th_content_type` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '缩略图MIME类型',`object_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '文件所属对象id',`object_type` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '文件所属对象类型,例如用户头像,评价图片',`attr` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '附加属性',`create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDBAUTO_INCREMENT = 1CHARACTER SET = utf8COLLATE = utf8_general_ci COMMENT = '文件记录表'ROW_FORMAT = Dynamic;-- postgre 自定义
create table if not exists "file_detail" (id VARCHAR(255) not null,url VARCHAR(255) not null,"size" BIGINT null,filename VARCHAR(255) null,original_filename VARCHAR(255) null,base_path VARCHAR(255) null,"path" VARCHAR(255) null,ext VARCHAR(255) null,content_type VARCHAR(255) null,platform VARCHAR(255) null,th_url VARCHAR(255) null,th_filename VARCHAR(255) null,th_size bigint null,th_content_type VARCHAR(255) null,object_id VARCHAR(255) null,object_type VARCHAR(255) null,attr VARCHAR(255) null,create_time TIMESTAMP null,project_id UUID null,tenant_id UUID null,primary key ("id"));-- Column comments
COMMENT ON TABLE file_detail IS '文件记录表';
COMMENT ON COLUMN public.file_detail.id IS '主键';
COMMENT ON COLUMN public.file_detail.url IS '文件访问地址';
COMMENT ON COLUMN public.file_detail."size" IS '文件大小,单位字节';
COMMENT ON COLUMN public.file_detail.filename IS '文件名称';
COMMENT ON COLUMN public.file_detail.original_filename IS '原始文件名';
COMMENT ON COLUMN public.file_detail.base_path IS '基础存储路径';
COMMENT ON COLUMN public.file_detail."path" IS '存储路径';
COMMENT ON COLUMN public.file_detail.ext IS '文件扩展名';
COMMENT ON COLUMN public.file_detail.content_type IS 'MIME类型';
COMMENT ON COLUMN public.file_detail.platform IS '存储平台';
COMMENT ON COLUMN public.file_detail.th_url IS '缩略图访问路径';
COMMENT ON COLUMN public.file_detail.th_filename IS '缩略图名称';
COMMENT ON COLUMN public.file_detail.th_size IS '缩略图大小,单位字节';
COMMENT ON COLUMN public.file_detail.th_content_type IS '缩略图MIME类型';
COMMENT ON COLUMN public.file_detail.object_id IS '文件所属对象id';
COMMENT ON COLUMN public.file_detail.object_type IS '文件所属对象类型,例如用户头像,评价图';
COMMENT ON COLUMN public.file_detail.attr IS '附加属性';
COMMENT ON COLUMN public.file_detail.create_time IS '创建时间';
COMMENT ON COLUMN public.file_detail.project_id IS '项目id';
COMMENT ON COLUMN public.file_detail.tenant_id IS '租户id';

参考

  • Springboot 中快速完成文件上传,整合多平台神器

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/391754.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

漏洞挖掘 | src中一次证书站有趣的SQL注入

一、确定站点 按照以前文章中提到的寻找可进站测试的思路&#xff0c;找到了某证书站的一处站点&#xff0c;通告栏中写明了初始密码的结构&#xff0c;因此我们可通过信息搜集进入该站点(可以考虑去搜集比较老的学号&#xff0c;因为这样的账号要么被冻结&#xff0c;要么就是…

AMD Product Specifications - AMD 产品规格汇总

AMD Product Specifications - AMD 产品规格汇总 1. Desktop, Laptop and Workstation Processor Specifications (台式处理器、笔记本电脑处理器和工作站处理器规格)2. Server Processor Specifications (服务器处理器规格)3. Embedded Processor Specifications (嵌入式处理器…

土耳其射击运动员尤素夫迪凯克在巴黎奥运会上成为互联网热门人物

这名51岁的男子以自己的方式获得了第二名,这对他的祖国来说是一个历史性的时刻。 这位冷静沉着的土耳其手枪射击运动员周二在 2024 年巴黎奥运会上获得银牌&#xff0c;在网上吸引了众多粉丝。 尤素夫迪克与他的搭档塞夫瓦尔伊莱达塔尔汉在混合团体 10 米气手枪比赛中获得第二…

jupyter notebook安装

1.安装 pip install notebook 2.显示配置文件&#xff1a; jupyter notebook --generate-config 3.修改代码路径&#xff1a; 编辑配置文件C:\Users\a\.jupyterjupyter_notebook_config.py 4.运行 jupyter notebook 会自动弹出http://localhost:8888/tree

QT 笔记

HTTPS SSL配置 下载配置 子父对象 QTimer *timer new QTimer; // QTimer inherits QObject timer->inherits("QTimer"); // returns true timer->inherits("QObject"); // returns true timer->inherits("QAbst…

保形分位数回归(CQR)

目录 简介1 介绍提纲式总结 分位数回归从数据中估计分位数 3 共性预测4 保形分位数回归(CQR)两个定理 6 实验7 结论 简介 保形预测是一种构造在有限样本中获得有效覆盖的预测区间的技术&#xff0c;无需进行分布假设。尽管有这种吸引力&#xff0c;但现有的保形方法可能是不必…

【文心智能体】梗图七夕版,一分钟让你看懂如何优化prompt,以及解析低代码工作流编排实现过程和零代码结合插件实现过程,依然是干货满满,进来康康吧

目录 背景什么是梗图梗图概念梗图结构 低代码开发最小运行单元大模型链提示词模板文心模板输出效果 测试工具链HTTP请求工具 梗图工具链全流程 梗图优化Prompt提示词优化后梗图结构提示词前后对比优化前效果优化后效果API接口BOS图片水印 梗图插件格式说明构思插件清单文件定义…

HTML-07.表格标签

一、要制作的表格如下 二、代码如下 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>表格标签<…

数据结构——双链表详解(超详细)

前言&#xff1a; 小编在之前已经写过单链表的创建了&#xff0c;接下来要开始双链表的讲解了&#xff0c;双链表比单链表要复杂一些&#xff0c;不过确实要比单链表更好进行实现&#xff01;下面紧跟小编的步伐&#xff0c;开启今天的双链表之旅&#xff01; 目录 1.概念和结构…

【已解决】没有密码,如何解除PPT的“只读方式”?

PPT可以设置有密码的“只读方式”&#xff0c;保护文件不被随意编辑更改。 在设置保护后&#xff0c;打开PPT时就会弹出对话框&#xff0c;提示需要“输入密码以修改或以只读方式打开”&#xff0c;也就是输入密码才能编辑修改PPT&#xff0c;如果点击“只读”也能打开文件&am…

[BJDCTF2020]Mark loves cat1

打开题目 发现这么多链接&#xff0c;以为要一点点去找功能上的漏洞。当你源代码&#xff0c;dirsearch&#xff0c;抓包等等操作之后&#xff0c;发现什么都没有。所以这题又是一道源码泄露题&#xff0c;上GItHack。扫描结果如下 http://63f29a80-e08b-43ae-a6d0-8e70fb02ea…

闪耀STIF2023国际科创节,望繁信科技荣获年度行业创新典范奖

2023年12月15日&#xff0c;望繁信科技在STIF2023第四届国际科创节暨DSC2023国际数字服务大会&#xff08;数服会&#xff09;活动评选中&#xff0c;斩获“2023年度行业创新典范”大奖。 作为科技创新与数字化服务领域最具影响力的年度盛会之一&#xff0c;STIF2023国际科创节…

目标检测——YOLOv10: Real-Time End-to-End Object Detection

YOLOv10是在YOLOv8的基础上&#xff0c;借鉴了RT-DETR的一些创新点改进出来的 标题&#xff1a;YOLOv10: Real-Time End-to-End Object Detection论文&#xff1a;https://arxiv.org/pdf/2405.14458源码&#xff1a;https://github.com/THU-MIG/yolov10 1. 论文介绍 在过去的几…

JAVA—面向对象编程高级

学习了一定基础后&#xff0c;开始更加深入的学习面向对象&#xff0c;包含static,final两个关键字&#xff0c;面向对象编程三大特征之继承和多态。以及对于抽象类&#xff0c;内部类&#xff0c;接口&#xff0c;枚举&#xff0c;泛型的学习。 目录 1.static &#xff08;…

原神自定义倒计时

<!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><title>原神倒计时</title><style>* {margin: 0;padding: 0;box-sizing: border-box;user-select: none;body {background: #0b1b2c;}}header {…

Javase--Date

1.Date简介 Date的学习: 1. java.util包下的类 2.用于日期、时间的描述 3. 实际上时距离一个固定时间点1970年1月1日00:00:00的毫秒数 4.我们常用的是格林威治时间:GMT UTC:世界调整时间 5.固定时间点:说的其实是本初子午线的时间。因此北京时间是1970年1月1日8:00:…

c++ 容器 vector

vector的意思就是向量&#xff0c;就是一个顺序表的意思&#xff0c;这个顺序表可以存任意的类型&#xff0c;因为其线性的内存特点&#xff0c;所以在stl里是经常被使用的存在。 vector vector既然要能储存任意的变量&#xff0c;那么就必须使用模板: 这里的T就是变量类型&a…

微信小程序之behaviors

目录 概括 Demo演示 进阶演示 1. 若具有同名的属性或方法 2. 若有同名的数据 3. 若有同名的生命周期函数 应用场景 最后 属性&方法 组件中使用 代码示例&#xff1a; 同名字段的覆盖和组合规则 概括 一句话总结: behaviors是用于组件间代码共享的特性, 类似一…

Docker简介 MacM1安装Docker

文章目录 1 Docker简介2 Docker VS 虚拟机1 Docker优势2 Docker用途 3 MacM1 下载安装Docker1 配置环境变量 4 配置Docker2 设置Docker资源3 设置Docker镜像 参考 1 Docker简介 Docker主要解决了软件开发和运行配置的问题&#xff0c;但是由于其功能的强大&#xff0c;也被应用…

LeetCode每日一题_600.不含连续1的非负整数

自己思路&#xff1a;暴力破解&#xff0c;但是超时 class Solution {public int findIntegers(int n) {int count0;String str2;for(int i 0;i<n;i){str2 Integer.toBinaryString(i);if(str2.contains("11")){count1;}}return n-count1;} }其他题解涉及动态规…