轻量级 S3 协议存储客户端

目前大家一般不会把二进制文件直接放在应用服务器上,而是存在“对象存储”的方案中,例如亚马逊的 AWS,阿里云的 OSS、Cloudflare R2 等。AWS 为最早的始作俑者,因此其 S3 协议也近乎标准化,各大厂商的对象存储方案都实现该协议。基本上各家都有提供方便的 SDK 可以用快速调用 S3 服务,而其中的原理就难度来说并不是太复杂,笔者一时“手痒”就想打造自己的 S3 客户端。该组件主打的就是一个轻量级,不超过十个类,基本覆盖日常 OSS 的操作。

当前该组件支持 S3 协议中以下的操作:

  • 列出桶 listBucket
  • 创建、删除桶 createBucket/deleteBucket
  • 上传文件、获取文件、删除文件 putObject/getObject/deleteObject

其他比较少用到的操作,暂且不实现了。

当前支持的厂商:阿里云 OSS、网易云 NOS、Cloudflare R2,其中 Cloudflare R2 是基于 SigV4 协议的。

安装

该组件源码在:https://gitee.com/sp42_admin/ajaxjs/tree/master/aj-backend/aj-playground/aj-s3client。

Maven 坐标:

<dependency>
    <groupId>com.ajaxjs</groupId>
    <artifactId>aj-s3client</artifactId>
    <version>1.0</version>
</dependency>

使用方法

第一步是设置好 OSS 各项参数,详见配置对象 Config

/**
 * 配置
 */
@Data
public class Config {
    /**
     * 访问 API
     */
    private String endPoint;

    /**
     * 访问 Key
     */
    private String accessKey;

    /**
     * 访问密钥
     */
    private String secretKey;

    /**
     * 存储桶名称
     */
    private String bucketName;

    /**
     * 签名中的标识,每个厂商不同
     */
    private String remark;
}

这个 POJO 你通过 Spring 注入到各个厂商实现就可以了。如果不用 Spring,最简单的就是这样子的:

在这里插入图片描述
OSS 各种调用 API,详见接口S3Client,一般懂 Java 的朋友都会,就不详细介绍了。

package com.ajaxjs.s3client;

import java.util.Map;

/**
 * S3 客户端
 */
public interface S3Client {
    /**
     * 列出存储桶中的所有对象
     *
     * @return XML List
     */
    String listBucket();

    /**
     * 列出存储桶中的所有对象
     *
     * @return XML List Map
     */
    Map<String, String> listBucketXml();

    /**
     * 创建一个存储桶(Bucket)
     *
     * @param bucketName 存储桶的名称,必须全局唯一
     * @return true=操作成功
     */
    boolean createBucket(String bucketName);

    /**
     * 删除一个存储桶(Bucket)
     *
     * @param bucketName 存储桶的名称
     * @return true=操作成功
     */
    boolean deleteBucket(String bucketName);

    /**
     * 将字节数据上传到指定的存储桶中
     *
     * @param bucketName 存储桶的名称
     * @param objectName 对象(文件)在存储桶中的名称
     * @param fileBytes  要上传的文件的字节数据
     * @return true=操作成功
     */
    boolean putObject(String bucketName, String objectName, byte[] fileBytes);

    /**
     * 将字节数据上传到指定的存储桶中
     *
     * @param objectName 对象(文件)在存储桶中的名称
     * @param fileBytes  要上传的文件的字节数据
     * @return true=操作成功
     */
    boolean putObject(String objectName, byte[] fileBytes);

    /**
     * 将字节数据上传到指定的存储桶中
     *
     * @param bucketName 存储桶的名称
     * @param objectName 对象(文件)在存储桶中的名称
     * @return true=操作成功
     */
    boolean getObject(String bucketName, String objectName);

    /**
     * 将字节数据上传到指定的存储桶中
     *
     * @param objectName 对象(文件)在存储桶中的名称
     * @return true=操作成功
     */
    boolean getObject(String objectName);

    /**
     * 删除指定的文件
     *
     * @param bucketName 存储桶的名称
     * @param objectName 要删除的文件名称
     * @return true=操作成功
     */
    boolean deleteObject(String bucketName, String objectName);

    /**
     * 删除指定的文件
     *
     * @param objectName 要删除的文件名称
     * @return true=操作成功
     */
    boolean deleteObject(String objectName);
}

单元测试的配置文件application.yml没有随着 VCS 提交,其内容如下:

S3Storage:
  Nso:
    accessKey: xx
    accessSecret: xx
    api: nos-eastchina1.126.net
    bucket: xx
  Oss:
    accessKeyId: xx
    secretAccessKey: xx
    endpoint: oss-cn-beijing.aliyuncs.com
    bucket: xx
  LocalStorage: # 本地保存
    absoluteSavePath: c:\temp\ # 若有此值,保存这个绝对路径上

开发感受

这类客户端的实现过程中,感受如下几点:

  1. 仍离不开 HTTP 通讯。所谓 OSS,本质围绕着文件服务进行:文件上传、文件删除、文件下载,比较特殊一点的就是“存储桶 Bucket”的概念,这一切与服务器之间沟通仍然通过 HTTP API 进行,故所以这客户端要封装好 HttpClient 这样子组件并进行 API 通讯的调用。Cloudflare R2 官方提供 Postman 直接示例,对于我再现 Java HTTP 请求很方便
  2. 既然是协议的通讯,如何身份认证是个问题。S3 协议认证方式是每次的 HTTP 请求头加入Authorization 字段,如何生成这个合法的签名值是相对复杂的过程,包括各种参数设定和加密,占了代码很大的篇幅。S3 签名有两个版本 SigV2、SigV4,本组件都支持。
  3. 虽然同为 S3 协议,但各厂商实现的产品均有不同程度上的出入,于是在代码设计上采用子类继承了来实现这种关系:BaseS3Client–>BaseS3ClientSigV2/BaseS3ClientSigV4–>各个厂商的实现
  4. 实现过程感觉最困难的是签名生成,稍有不慎,生成的签名不合法则出现校验不通过的情况。SigV2 签名的生成方式还是比较简单的,类似阿里云文档里面的介绍:在这里插入图片描述但是 SigV4 则复杂得多,于是我找了一个很好开源实现 aws-v4-signer-java,零依赖,我简化了不少代码并将其重构了。另外,阿里云的文档也介绍得很清楚,详见这里和源码。
  5. 单元测试依然很重要,尤其写组件的时候,或者重构的时候,很多时候要把问题复现出来,单测必不可少,也能提高开发的效率。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【C++类和对象】构造函数与析构函数

&#x1f49e;&#x1f49e; 前言 hello hello~ &#xff0c;这里是大耳朵土土垚~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#x…

【grpc】grpc进阶二,grpc认证方式

本章把之前的工程结构改了一下&#xff0c;创建了 server 和 client 两个目录&#xff0c;分别把 server.go&#xff0c;client.go 移动过去。 接下来会介绍 grpc 的 TLS 认证和 Oauth2 一、TLS认证 在进行功能验证是需要使用 openssl 创建自有证书&#xff0c;下面是创建步骤…

Paddle实现人脸对比(二)

我之前发过一篇基于孪生网络的人脸对比的文章&#xff0c;这篇文章也到了百度的推荐位置&#xff1a; 但是&#xff0c;效果并不是很好。经过大量的搜索&#xff0c;我发现了一种新的方法&#xff0c;可以非常好的实现人脸对比。 原理分析 我们先训练一个普通的人脸分类模型&…

关于机器学习/深度学习的一些事-答知乎问(二)

进化算法与深度强化学习算法结合如何进行改进&#xff1f; &#xff08;1&#xff09;进化算法普遍存在着样本效率低下的问题&#xff0c;虽然其探索度较高&#xff0c;但其本质为全局随机性搜索&#xff0c;需要在整个回合结束后才能更新其种群&#xff0c;而深度强化学习在每…

深入理解计算机网络分层结构

一、 为什么要分层&#xff1f; 计算机网络分层的主要目的是将复杂的网络通信过程分解为多个相互独立的层次&#xff0c;每个层次负责特定的功能。这样做有以下几个好处&#xff1a; 模块化设计&#xff1a;每个层次都有清晰定义的功能和接口&#xff0c;使得网络系统更易于设…

023——搭建图形化客户端(基于pySimpleGUI)

目录 一、pysimplegui 1.1 安装 1.2 测试 二、 pysimplegui学习 2.1 学习地址 2.2 人类早期驯服pysimplegui珍贵流水账 三、 实现项目专属的界面 一、pySimpleGUI 1.1 安装 pip install pysimplegui -i https://pypi.tuna.tsinghua.edu.cn/simple Command pip not fo…

GAN:对抗生成网络【通俗易懂】

一、概述 对抗生成网络&#xff08;GAN&#xff09;是一种深度学习模型&#xff0c;由两个神经网络组成&#xff1a;生成器G和判别器D。这两个网络被训练来协同工作&#xff0c;以生成接近真实数据的新样本。 生成器的任务是接收一个随机噪声向量&#xff0c;并将其转换为与真…

【Web】DASCTF X GFCTF 2022十月挑战赛题解

目录 EasyPOP hade_waibo EasyLove BlogSystem EasyPOP 先读hint.php sorry.__destruct -> secret_code::secret() exp: $anew sorry(); $bnew secret_code(); $a->password"suibian"; $a->name"jay"; echo serialize($a); 真暗号啊&…

基于Java停车场管理系统设计与实现(源码+部署文档)

博主介绍&#xff1a; ✌至今服务客户已经1000、专注于Java技术领域、项目定制、技术答疑、开发工具、毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精彩专栏 推荐订阅 &#x1f447;&#x1f3fb; 不然下次找不到 Java项目精品实…

即插即用模块之DO-Conv(深度过度参数化卷积层)详解

目录 一、摘要 二、核心创新点 三、代码详解 四、实验结果 4.1Image Classification 4.2Semantic Segmentation 4.3Object Detection 五、总结 论文&#xff1a;DOConv论文 代码&#xff1a;DOConv代码 一、摘要 卷积层是卷积神经网络(cnn)的核心组成部分。在本文中…

【Java虚拟机】简单易懂的ZGC原理分析

简单易懂的ZGC原理分析 GC垃圾收集器ZGC的特点ZGC相关技术Region染色指针 & 转发表 & 读屏障染色指针转发表读屏障 内存多重映射 ZGC流程详解ZGC与其他垃圾搜集器比较与CMS比较与G1比较 GC垃圾收集器 GC垃圾收集器的作用就是帮我们清理堆内存里面的垃圾&#xff0c;无…

第1章、react基础知识;

一、react学习前期准备&#xff1b; 1、基本概念&#xff1b; 前期的知识准备&#xff1a; 1.javascript、html、css&#xff1b; 2.构建工具&#xff1a;Webpack&#xff1a;https://yunp.top/init/p/v/1 3.安装node&#xff1a;npm&#xff1a;https://yunp.top/init/p/v/1 …

cmake制作并链接动静态库

cmake制作并链接动静态库 制作静态库add_library(库名称 STATIC 源文件1 [源文件2] ...)LIBRARY_OUTPUT_PATH指定库的生成路径 制作动态库add_library(库名称 SHARED 源文件1 [源文件2] ...) 连接动静态库link_libraries连接静态库link_directories到哪个路径去找库target_link…

UnityShader学习计划

1.安装ShaderlabVS,vs的语法提示 2. 常规颜色是fixed 3.FrameDebugger调试查看draw的某一帧的全部信息&#xff0c;能看到变量参数的值

雅马哈电钢琴YDP145

数据线&#xff1a;MIDI 琴可以通过MIDI、线直接连接手机&#xff0c;播放声音 琴通过线连接电脑&#xff0c;不能直接播放声音 https://www.bilibili.com/video/BV1ws4y1M7yw 操作&#xff1a; https://usa.yamaha.com/support/updates/yamaha_steinberg_usb_driver_for_win…

王道汽车4S企业管理系统 SQL注入漏洞复现

0x01 产品简介 王道汽车4S企业管理系统(以下简称“王道4S系统”)是一套专门为汽车销售和维修服务企业开发的管理软件。该系统是博士德软件公司集10余年汽车行业管理软件研发经验之大成,精心打造的最新一代汽车4S企业管理解决方案。 0x02 漏洞概述 王道汽车4S企业管理系统…

完美照片由构图决定,摄影构图基础到进阶

一、资料描述 本套摄影构图资料&#xff0c;大小1.04G&#xff0c;共有51个文件。 二、资料目录 新手必备-摄影构图技巧.doc 无忌版的《摄影构图学》.pdf 完美照片的十大经典拍摄技法.pdf 数码摄影曝光手边书.pdf 数码摄影不求人.30天学会数码摄影构图.pdf 数码单反摄影…

sheng的学习笔记-AI-决策树(Decision Tree)

AI目录&#xff1a;sheng的学习笔记-AI目录-CSDN博客 目录 什么是决策树 划分选择 信息增益 增益率 基尼指数 剪枝处理 预剪枝 后剪枝 连续值处理 另一个例子 基本步骤 排序 计算候选划分点集合 评估分割点 每个分割点都进行评估&#xff0c;找到最大信息增益的…

靠谱的大型相亲交友婚恋平台有哪些?相亲app软件前十名

靠谱交友软件&#xff0c;个人感觉还是要选择大型的&#xff0c;口碑好的进行选择&#xff0c;以下是我用过的婚恋平台&#xff0c;分享给大家 1、丛丛 这是我用的最久的一款脱单小程序&#xff0c;我老公就是在这个小程序找到的&#xff01;&#xff01;&#xff01; 这是一款…

CSS边框

目录 内容区&#xff08;content&#xff09;&#xff1a; 边框&#xff08;border&#xff09;&#xff1a; 前言&#xff1a; 示例&#xff1a; 内容区&#xff08;content&#xff09;&#xff1a; 内容区就是盒子里面用来存放东西的区域&#xff0c;里面你可以随便放如:…