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

06-01 1517阅读

文章目录

  • 概述
  • 快速入门
    • 添加依赖
    • 添加配置文件
    • 编码
      • 显式的开启文件上传功能
      • 上传
      • 文件是否存在、下载、删除
      • 监听器
      • 切面
      • 表设计
      • 参考

        概述

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

        云存储

        在开发过程当中,会使用到存文档、图片、视频、音频等等,这些都会涉及存储的问题,文件可以直接存服务器,但需要考虑带宽和存储空间,另外一种方式就是使用云存储。目前主流的云存储有阿里云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 协议的平台。

        支持的平台如下图:

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

        快速入门

        添加依赖

            
            
                cn.xuyanwu
                spring-file-storage
                2.1.0
            
            
            
                com.huaweicloud
                esdk-obs-java
                3.22.12
            
            
            
                com.aliyun.oss
                aliyun-sdk-oss
                3.16.1
            
        

        添加配置文件

        注:以下配置是 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 {
            @Autowired
            private 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() {
            @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");
        

        切面

        工具还提供了每种操作的切面,可以在每个动作的前后进行干预,比如打日志,实现 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;
            }
        }
        

        表设计

        -- 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 = InnoDB
          AUTO_INCREMENT = 1
          CHARACTER SET = utf8
          COLLATE = 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 中快速完成文件上传,整合多平台神器
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

目录[+]

取消
微信二维码
微信二维码
支付宝二维码