Springboot项目实战:一个依赖解决多平台OSS文件上传问题,以后就用这个 oss-spring-boot-starter

news2025/8/2 21:18:43

本文解决痛点。是否再不同项目需要不同的OSS二头疼。

  • A项目用七牛云,B项目使用阿里云。
  • 不想用七牛云了,还是改用华为云吧。
  • 同个项目使用不同的 bucketName

遇到这种种情况,本文提供一个依赖搞定多云OSS 适配问题

什么是OSS?

数据以对象(Object)的形式存储在OSS的存储空间(Bucket )中。如果要使用OSS存储数据,您需要先创建Bucket,并指定Bucket的地域、访问权限、存储类型等属性。创建Bucket后,您可以将数据以Object的形式上传到Bucket,并指定Object的文件名(Key)作为其唯一标识。

OSS以HTTP RESTful API的形式对外提供服务,访问不同地域需要不同的访问域名(Endpoint)。当您请求访问OSS时,OSS通过使用访问密钥(AccessKey ID和AccessKey Secret)对称加密的方法来验证某个请求的发送者身份。

OSS在项目中的使用

OSS对象存储在目前大部分项目中必不可少的存在,如下图所示。

image-20230417163846184

  1. 一般项目使用OSS对象存储服务,主要是对图片、文件、音频等对象集中式管理权限控制,管理数据生命周期等等,提供上传,下载,预览,删除等功能。
  2. 通过OSS部署前端项目。
  3. 配合CDN使用
  4. 减少对业务服务器的流量

什么是AmazonS3

  • https://docs.aws.amazon.com/zh_cn/AmazonS3/latest/userguide/Welcome.html

Amazon Simple Storage Service(Amazon S3,Amazon简便存储服务)是 AWS 最早推出的云服务之一,经过多年的发展,S3 协议在对象存储行业事实上已经成为标准。

  1. 提供了统一的接口 REST/SOAP 来统一访问任何数据
  2. 对 S3 来说,存在里面的数据就是对象名(键),和数据(值)
  3. 不限量,单个文件最高可达 5TB,可动态扩容。
  4. 高速。每个 bucket 下每秒可达 3500 PUT/COPY/POST/DELETE 或 5500 GET/HEAD 请求。
  5. 具备版本,权限控制能力
  6. 具备数据生命周期管理能力

作为一个对象存储服务,S3 功能真的很完备,行业的标杆,目前市面上大部分OSS对象存储服务都支持AmazonS3,本文主要讲解的就是基于AmazonS3实现我们自己的 Spring Boot Starter。

阿里云OSS兼容S3

https://help.aliyun.com/document_detail/451966.html?spm=a2c4g.389025.0.0.170a27a2KuNpvV

image-20230417163733831

七牛云对象存储兼容S3

https://developer.qiniu.com/kodo/4088/s3-access-domainname

image-20230417164035296

腾讯云COS兼容S3

https://cloud.tencent.com/document/product/436/41284

image-20230417164202501

Minio兼容S3

http://minio.org.cn/product/s3-compatibility.html

image-20230417164311776

我们为什么要基于AmazonS3实现 Spring Boot Starter

原因:市面上OSS对象存储服务基本都支持AmazonS3,我们封装我们的自己的starter那么就必须考虑适配,迁移,可扩展。比喻说我们今天使用的是阿里云OSS对接阿里云OSS的SDK,后天我们使用的是腾讯COS对接是腾讯云COS,我们何不直接对接AmazonS3实现呢,这样后续不需要调整代码,只需要去各个云服务商配置就好了

使用

引入

<dependency>
    <groupId>com.admin4j</groupId>
    <artifactId>oss-spring-boot-starter</artifactId>
    <version>0.1.1</version>
</dependency>

oss-spring-boot-starter 最新版查询 https://central.sonatype.com/artifact/com.admin4j/oss-spring-boot-starter/

配置文件

admin4j:
  oss:
    endpoint: "http://192.168.1.13:9901"
    region: cn-east-1
    access-key: 4NdsQG6g6hzJfwko
    secret-key: zeSSPz3WC3Wn4zBZsYtxK9YXhZ7Hjnnv
    bucket-name: oss-template
    enable: true

OssTemplate 使用直接操作 OSS

@SpringBootTest
public class OssTest {

    @Autowired
    OssTemplate ossTemplate;

    @Test
    /**
     * 创建 Bucket
     */
    public void testCreateBucket() {

        ossTemplate.createBucket("oss-template");
    }

    @Test
    /**
     * 获取所有Bucket
     */
    public void testGetAllBuckets() {

        List<Bucket> allBuckets = ossTemplate.getAllBuckets();
        System.out.println("allBuckets = " + allBuckets);
    }

    @Test
    /**
     * 上传文件
     */
    public void testPut() throws IOException {

        FileInputStream fileInputStream = new FileInputStream("C:\\Users\\andanyang\\Downloads\\012408-167976504839ee.jpg");
        PutObjectResult putObjectResult = ossTemplate.putObject("oss-template", "test/Test.jpg", fileInputStream);
        System.out.println("putObjectResult = " + putObjectResult);
    }

    @Test
    /**
     * 获取文件
     */
    public void testGet() throws IOException {

        String objectURL = ossTemplate.getObjectURL("oss-template", "test/Test.jpg", 1, TimeUnit.DAYS);
        System.out.println("objectURL = " + objectURL);
    }


}

UploadFileService web 上传文件

@RestController
@RequestMapping("oss")
public class OssController {

    @Autowired
    UploadFileService uploadFileService;

    @PutMapping
    public R upload(MultipartFile file) throws IOException {


        UploadFileVO image = uploadFileService.upload("image", file);

        System.out.println("image = " + image);

        String previewUrl = uploadFileService.getPreviewUrl(image.getKey());

        System.out.println("previewUrl = " + previewUrl);

        return R.ok(image);
    }
}

自动以上传文件

继承SimpleOSSUploadFileService

  • 重写 generateFilePath() 方法 ,自定义生成文件名
  • 重写 beforeUpload 上传前钩子 true 可以上传 false 不用上传(比如根据md5/path 检查文件已存在)
  • 重写 afterUpload 上传完成钩子,可以保存上传记录等
  • 注入多个继承于SimpleOSSUploadFileService bean,可以实现同个项目,上传到不同OSS或者不同Bucket的目的

项目地址

https://github.com/admin4j/admin4j-framework/tree/master/oss-spring-boot-starter

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【UE 控件蓝图】菜单及功能实现

素材资源连接&#xff1a;百度网盘 请输入提取码 密码&#xff1a;fvcw 效果 步骤 1. 创建蓝图&#xff0c;父类为“HUD” 命名为“MainMenuHUD”并打开 在事件图表中添加如下节点&#xff1a; 2. 创建控件蓝图&#xff0c;命名为“MainMenuWidget” 此时在“MainMenuHUD”的…

全方位解析 pinia

前言 Vue3已经推出很长时间了&#xff0c;它周边的生态也是越来越完善了。之前我们使用Vue2的时候&#xff0c;Vuex可以说是必备的&#xff0c;它作为一个状态管理工具&#xff0c;给我们带来了极大的方便。Vue3推出后&#xff0c;虽然相对于Vue2很多东西都变了&#xff0c;但…

私有句柄表

私有句柄表 实验环境 win7 x86 什么是私有句柄表&#xff1f; 私有句柄表是操作系统内部的一种数据结构&#xff0c;用于存储一个进程所拥有的句柄&#xff08;或称为句柄对象&#xff09;的信息。在操作系统中&#xff0c;句柄是一个标识符&#xff0c;用于唯一标识一个对…

【iOS】NSError**和__autoreleasing场景

前言 在看JSONModel源码的时候&#xff0c;JSONModel的自定义Error的方法一直在报错 - (BOOL)validate:(NSError *__autoreleasing *)error {}这个方法在定义error的时候添加上了__autoreleasing修饰符&#xff0c;涉及到了__autoleasing的显式隐式调用就去了解了一下。 发现…

【C++ 三】一维数组、二维数组

数组概述、一维数组、二维数组 文章目录数组概述、一维数组、二维数组前言1 数组1.1 概述2 一维数组2.1 一维数组定义方式2.2 一维数组数组名2.3 冒泡排序3 二维数组3.1 二维数组定义方式3.2 二维数组数组名总结前言 本文包含数组概述、一维数组、二维数组。 1 数组 1.1 概述…

python web 医院加密处方系统

医院加密处方系统 环境要求&#xff1a; 1、python3.8 2、vue 3、django 4、mysql 5、ruoyi快速开发框架 登录界面 可以登录和注册&#xff0c;注册分三个角色&#xff0c;主治医师和药品医师还有配制医师&#xff0c;有验证码和用户权限功能&#xff0c;用户管理、部…

AIGC下一站:期待、警惕充斥着AI剪辑师的世界

上月底&#xff0c;名为“chaindrop”的 Reddit 用户&#xff0c;在 r/StableDiffusion subreddit 上分享了一个由人工智能生成的视频&#xff0c;在业内引起了不小的争议。 视频中&#xff0c;一个由 AI 生成的丑陋畸形的 “威尔史密斯”&#xff0c;以一种可怕的热情将一把意…

vba:消息框基础,massagebox

常量常量值说明vbOKOnly0只显示“确定”按钮&#xff08;缺省值&#xff09;VbOKCancel1显示“确定”和“取消”按钮VbAbortRetryIgnore2显示“终止”、“重试”和“忽略” 按钮VbYesNoCancel3显示“是”、“否”和“取消”按钮VbYesNo4显示“是”和“否”按钮VbRetryCancel5显…

pkg-config

前言 在介绍 pkg-config 之前&#xff0c;先讲一个我的经历。 有一次我想用 libgtk 库在 ubuntu 上实现一个简单的图形界面&#xff0c;就像下面代码 #include <gtk/gtk.h>int main(int argc, char *argv[]) {GtkWidget *window;gtk_init(&argc, &argv);window…

UG NX二次开发(C#)-建模-获取曲面的法矢

文章目录 1、前言2、曲面的法矢示例3、获取曲面的法矢3.1 采用 uFModl.AskFaceProps实现3.2采用 uFSo实现4、结论1、前言 在UG NX二次开发过程中,我们想获取曲面的法矢,是通过ufun函数来获取的。我们以一个平面和一个曲面来说明其开发过程。 2、曲面的法矢示例 创建一张曲…

商城系统开发方案分析

互联网的不断发展&#xff0c;电商行业已经成为了当前最重要的商业形式之一。商城系统的开发也因此而备受关注。商城系统的开发是针对B2C、B2B2C等多种商业模式&#xff0c;如用户熟知的SHOP、商派等一系列商城系统&#xff0c;将商品和服务进行在线销售的一个综合性平台。那么…

【软考备战·希赛网每日一练】2023年4月17日

文章目录一、今日成绩二、错题总结第一题第二题第三题第四题三、知识查缺题目及解析来源&#xff1a;2023年04月17日软件设计师每日一练 一、今日成绩 二、错题总结 第一题 解析&#xff1a; 第二题 解析&#xff1a; 第三题 解析&#xff1a; SCAN调度算法 也叫 “电梯”算…

RocketMQ 发送批量消息、过滤消息和事务消息

前面我们知道RocketMQ 发送延时消息与顺序消息&#xff0c;现在我们看下怎么发送批量消息、过滤消息和事务消息。 发送批量消息 限制是这些批量消息应该有相同的 topic&#xff0c;相同的 waitStoreMsgOK&#xff0c;而且不能是延时消息。 此外&#xff0c;这一批消息的总大小…

如何合理选择ClickHouse表主键

ClickHouse提供索引和数据存储的复杂机制&#xff0c;能够实现在高负载下仍有优异的读写性能。当创建MergeTree表时需要选择主键&#xff0c;主键影响大多数查询性能。本文介绍主键的工作原理&#xff0c;让我们知道如何选择合适的主键。 设置主键 MergeTree表可以设置主键&am…

香橙派5使用RK3588S内置NPU加速yolov5推理,实时识别数字达到50fps

前言&#xff1a; 香橙派5采用了RK3588S&#xff0c;内置的NPU达到了6Tops的算力&#xff0c;博主这里记录一下自己的踩坑过程&#xff0c;好不容易做出来的不能以后忘记了&#xff08;手动狗头&#xff09;。这里博主还在B站上发布了效果视频&#xff0c;大家感兴趣的话可以看…

TensorFlow 和 Keras 应用开发入门:1~4 全

原文&#xff1a;Beginning Application Development with TensorFlow and Keras 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 本文来自【ApacheCN 深度学习 译文集】&#xff0c;采用译后编辑&#xff08;MTPE&#xff09;流程来尽可能提升效率。 不要担心自己的形…

Java 中的 非并发容器

1.四大类容器 java中容器主要有四大类&#xff0c;如下图所示 2.非并发容器 1) List 类 List 类 不支持并发的有 ArrayList 与 LinkedList ArrayList 底层实现 ArrayList 底层为 数组&#xff0c;由于数组的特性&#xff0c;非常适合用于 查询多&#xff0c;增删改的业务…

【数据结构学习1】数据结构

目录数据结构定义数据结构的构成逻辑结构逻辑结构的类型存储结构数据运算数据类型和抽象数据类型算法定义分析基础时间复杂度分析事前分析估算法 -> 分析算法的执行时间时间复杂度时间复杂度类型简化的算法时间复杂度分析空间复杂度分析数据结构 定义 数据&#xff1a;所有…

工作流调度系统 Azkaban介绍与安装(一)

文章目录前言1、为什么要用工作流调度系统2、常见的工作流调度系统1 集群规划2 配置 MySQL3 配置 Executor Server3.1 修改 azkaban.properties3.2 启动3.3 激活4 配置 Web Server4.1 修改 azkaban.properties4.2 修改azkaban-users.xml文件&#xff0c;添加 atguigu 用户4.3 启…

VM 虚拟机没有网络,无法Ping通

场景&#xff1a; 虚拟机用过&#xff0c;之前一切正常&#xff0c;使用NAT模式联网&#xff0c;配置了静态IP换了路由器&#xff0c;推测是主机IP网段变了无法使用ssh工具连接虚拟机&#xff0c;且相互都ping不通&#xff08;后来经历了主机可以ping通虚拟机&#xff0c;虚拟…