【服务对接】✈️SpringBoot 项目整合华为云 obs 对象存储服务

news2024/11/15 8:20:14

目录

👋前言

👀一、环境准备

🌱二、整合实现

        1.依赖引入

        2.准备 AK 和 SK

​        3.配置类

        4.obs 工具类封装

💞️三、测试使用

🍻四、 obs 客户端

 📫五、章末


👋前言

        小伙伴们大家好,上次了解了如何通过 Java 将文本转为语音,是借助 Jacob 工具实现,可以说是引入了第三方工具类,通过 java 代码调用该工具提供的 api 即可实现我们想要的功能,也算是简单的调用第三方组件;在生产项目中也常见这种三方对接,比如最近了解的华为云对象存储服务,需要将用户所上传的图片文件转移到别的服务,而不是存储在服务器上,这种就可以借助三方服务实现,以减少服务器存储压力,并且适合微服务项目使用;

👀一、环境准备

        1.因为是基于生产项目整合华为云 obs 所以本篇文章不会从如何注册华为云账号开始,本篇文章基于已有华为云存储的鉴权 Key 实现,我们只需要这些 关键 key 值即可,以及开发文档

        这里给大家收集了华为云官方提供的文档可以参考下:

https://console.huaweicloud.com/apiexplorer/#/sdkcenter/OBS?lang=Java

        2.本地项目使用的是 SpringBoot 项目,可以通过 Spring Intilior 简单的创建一个

🌱二、整合实现

        1.依赖引入

        除了关键 key 值以外,我们需要在代码中调用华为云对象存储服务的 api (以下简称 obs),所以需要引入相应的依赖,在pom.xml 文件中加入以下内容,刷新 maven 即可自动下载所需依赖,版本可以自己选择更改

        <dependency>
            <groupId>com.huaweicloud</groupId>
            <artifactId>esdk-obs-java</artifactId>
            <version>3.20.6.1</version>
        </dependency>
        2.准备 AK 和 SK

        这两个属性在华为云接口文档上也有标明 ,将有效的 key 值放到项目的配置文件中,本地使用的是 yml 文件,所以格式如下:    

huawei:
  obs:
    endpoint: obs.cn-east-3.myhuaweicloud.com
    accessKey: abcde*************
    secretAccessKey: adcde***********
    bucketName: my-test-bucket
    expiration: 60

         注:这里的额外几个参数意思如下:

        bucketName: 像阿里云oss,华为云obs 这些服务的存储都有一个重要的概念,bucket 简称桶,相当于一个文件夹,里面可以存放很多文件,主要的作用就是区分存储位置,也是在管理页面自己设置,本地设置好之后,后续代码调用上传的都是指定的 bucket 内,方便管理

        endPoint: 在obs文档上有说明,本地根据地区选择的是 华东-上海二 终端节点

        expiration: 指定生成文件下载链接的有效时长(秒)

         3.配置类

        配置文件整理好后,为了后续方便代码调用,需要将 obs 配置映射为一个文件对象,也就是 bean 实例,如下:

        @ConfigurationProperties 中指定了映射的配置内容为 huawei.obs 开头的内容

        @Component 注解中指定了改 bean 实例的名称,这么做是为了防止后续项目启动时找到重名的 bean 导致报错,因为引入的包中可能含有同名的类,这样在注入的时候也指定一下名称,可以避免很多意意想不到的错误

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Component("OBSProperties")
@ConfigurationProperties(prefix = "huawei.obs")
public class ObsProperties {

    private String endpoint;
    private String accessKey;
    private String secretAccessKey;
    private String bucketName;
    private Long expiration;
}
        4.obs 工具类封装
@Component
public class ObsUtil {

    private ObsClient obsClient;


    @Resource(name = "OBSProperties")
    private ObsProperties obsProperties;


    //初始化 ObsUtil 工具类 bean
    @PostConstruct
    public void init() {
        obsClient = new ObsClient(obsProperties.getAccessKey(), obsProperties.getSecretAccessKey(),obsProperties.getEndPoint());
    }

    //注意这里传进来的参数是处理后的图片 base64 参数,处理方法只需要调用 api,这里不做过多解释,可以上网查询转换方法,另外是指定的文件名称和bucket名称,上传后的文件将是以该 fileName 存在于该bucket 内
    //此方法是用于上传文件,内部调用了 obs 的含有 MD5 参数校验的api方法
    public void uploadPic(String base64, String fileName) {
        byte[] bytes = transBase64ToByte(base64);
        ObjectMetadata meta = new ObjectMetadata();
        // 设置MD5校验。
        String md5 = toBase64String(calculateMd5(bytes));
        meta.setContentMd5(md5);
        try (InputStream inputStream = new ByteArrayInputStream(bytes)) {
            PutObjectResult result = obsClient.putObject(obsProperties.getBucketName(), fileName, inputStream,meta);
        } catch (Exception e) {
            log.error("Upload failed: ", e);
        }
    }

// 计算 MD5 值的方法
    private static byte[] calculateMd5(byte[] data) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            return md.digest(data);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("MD5 algorithm not found.", e);
        }
    }

    // 将字节数组转换为 Base64 编码的字符串
    private static String toBase64String(byte[] bytes) {
        return Base64.getEncoder().encodeToString(bytes);
    }

    //该方法是用于检查bucket 内是否有指定文件,内部调用了 obs 的获取文件方法
    public Boolean checkExist(String fileName) {
        ObsObject object = null;
        InputStream inputStream = null;
        try {
            object = ObsClient.getObject(bucketName, fileName);
            inputStream = object.getObjectContent();
            if (inputStream != null) {
                return true;
            }
        } catch (Exception e) {
            log.error("请求异常:{}", fileName, e);
            return false;
        } finally {
            // 确保关闭 InputStream
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                log.error("关闭 InputStream 异常", e);
            }
        }
        return false;
    }
   

    //该方法是用于获取指定时间内的文件下载链接
    public String getPicViewUrlByInternal(String fileName) {
        Boolean aBoolean = checkExist(fileName,obsProperties.getBucketName());
        if (!aBoolean) {
            return null;
        }
        // 生成以GET方法访问的签名URL,访客可以直接通过浏览器访问相关内容。
        String url = generatePresignedUrl(obsProperties.getExpiration(), fileName,obsProperties.getBucketName());
        return url;
    }

    private static String generatePresignedUrl(Long expire,String fileName,String bucketName) {
        TemporarySignatureResponse response = null;
        try {
            // URL有效期,3600秒
            //long expireSeconds = 3600L;
            TemporarySignatureRequest request = new TemporarySignatureRequest(HttpMethodEnum.GET, expire);
            request.setBucketName(bucketName);
            request.setObjectKey(fileName);
            response = obsClient.createTemporarySignature(request);
        } catch (ObsException e) {
            log.error("get obs failed :{}", e.getMessage());
            throw new ServiceException(Messages.getByCode("errors.obs.urlError"));
        }
        return Optional.ofNullable(response)
                .map(TemporarySignatureResponse::getSignedUrl)
                .orElse(null);
    }

}

💞️三、测试使用

        在 项目 test/java 下创建单元测试类,这里知识给大家做个展示,平时写好接口之后如何在单元测试类中测试,这里不做具体测试(由于设备原因等,后续也许会更新)

        注:单元测试类必须写在 test 目录下,否则会有注解报错问题

        @SpringBootTest 注解指定了项目启动类,根据自己项目改变

        @SpringRunner 不用改,固定的即可

        @Test 标注为测试方法,可以开启调试或运行功能

@SpringBootTest(classes = TestApplication.class)
@Slf4j
@RunWith(SpringRunner.class)
public class ObsTest {

    @Resource
    private ObsUtil obsUtil;


    @Test
    public void TestUtil(){

        obSUtil...
    }

}

🍻四、 obs 客户端

        当然除了代码中的调用方式,华为云也是有相对应的管理客户端,通过该应用也可以管理 bucket 文件的上传和删除,当然我们使用的话主要是用来检查文件是否上传成功之类的

        可以搜索 OBS Browser ,下载到本地启动之后的登录页面,选择 AK 方式登录,也就是代码配置文件中的 ak ,账号名这里可以自定义,重要的是 AccessKey 和 Secret Access Key ,访问路径可以不用填写

        登录后的界面如下:点击 bucket 会进入到桶内可以查看当前 bucket 内有哪些文件

 📫五、章末

        另外,因为设备等一些原因,没有对工具类方法测试,可能会有一些小问题,但是后续可能会更新

        文章到这里就结束了~

后续补充:

        1.下载图片时指定水印处理

        添加水印操作,obs提供了相应的api,具体的水印参数配置规则,可以参考官方文档,使用如下:

设置水印_对象存储服务 OBS_华为云

            TemporarySignatureRequest request = new TemporarySignatureRequest(HttpMethodEnum.GET, expire);
            request.setBucketName(bucketName);
            request.setObjectKey(fileName);
            HashMap<String, Object> queryParams = new HashMap<>();
            //例如这里指定的水印参数,"x-image-process"key是固定的,后面的value就是自定义的水印参数,text 指定的是自定义水印内容(经过base64编码后的,这里的是处理后的文本
            queryParams.put("x-image-process", "image/watermark,text_ MTIzNDU2,color_000000,size_50");
            request.setQueryParams(queryParams);
            response = obsClient.createTemporarySignature(request);
        } catch (ObsException e) {

         通过这种方式设置的水印,response返回值中的signUrl链接下载下来的图片就是经过水印处理后的图片了

        

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

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

相关文章

2024国赛数学建模C题完整论文:农作物的种植策略

农作物种植策略优化的数学建模研究&#xff08;完整论文&#xff0c;持续更新&#xff0c;大家持续关注&#xff0c;更新见文末名片 &#xff09; 摘要 在本文中&#xff0c;建立了基于整数规划、动态规划、马尔科夫决策过程、不确定性建模、多目标优化、相关性分析、蒙特卡洛…

Packet Tracer - 单区域OSPFv2的配置方法以及思路

Packet Tracer - 单区域OSPFv2的配置思路 1、思路前夕查看 做这个的时候大家了解一下通配符&#xff0c;不然不理解这个东西为什么子网掩码为什么会取反 这里给大家简单演示一下 2、使用进程 ID 10 在所有路由器上激活 OSPF。 在 Headquarters 网络中的路由器上使用 network…

FxFactory 8 for Mac 视觉特效插件包安装

Mac分享吧 文章目录 介绍页面效果一、下载软件二、开始安装1、Install安装2、显示软件页面&#xff0c;表示安装成功3、补丁安装 三、注意事项1、若已安装过其他版本&#xff0c;需要使用软件自带的卸载功能进行软件卸载&#xff0c;再安装此版本 安装完成&#xff01;&#x…

pod install 报错处理

由于墙的原因&#xff0c;pod install 、 pod update经常报错 有效的解决方案(推荐)&#xff1a; 以SnapKit为例 找不报错的同事要以下两个文件&#xff08;指定的版本&#xff09; 1. /Users/xxx/Library/Caches/CocoaPods/Pods/Release/SnapKit 2. /Users/xxx/Library/Cac…

后缀表达式转中缀表达式

假定有后缀表达式1 2 3 4 * 5 – &#xff0c;请将它转化为前缀表达式。 利用表达式树&#xff1a; 1.从左到右扫面后缀表达式&#xff0c;一次一个符号读入表达式。2.如果符号是操作数&#xff0c;那么就建立一个单节点树并将它推入栈中。如果符号是操作符&#xff0c;那么…

针对不同区域的摄像头,完成不同的算法配置的智慧快消开源了

智慧快消视频监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒&#xff0c;省去繁琐重复的适配流程&#xff0c;实现芯片、算法、应用的全流程组合&#xff0c;从而大大减少企业级应用约95%的开发成本。 基于多年的深度…

JAVAEE初阶第六节——网络编程套接字

系列文章目录 JAVAEE初阶第六节——网络编程套接字 文章目录 系列文章目录JAVAEE初阶第六节——网络编程套接字 一. 网络编程基础1. 为什么需要网络编程2. 什么是网络编程3.网络编程中的基本概念 3.1 发送端和接收端 3.2 请求和响应 3.3 客户端和服务端 4. 常见的客户端服务…

求二叉树的深度——(力扣c语言)

题目如下&#xff1a; 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3示例 2&#xff1a; 输入&#xff1a…

[网络编程]TCP和UDP的比较 及 通过java用UDP实现网络编程

文章目录 一. 网络编程套接字TCP和UDP的特点有连接 vs 无连接可靠传输 vs 不可靠传输面向字节流 vs 面向数据报全双工 vs 半双工 二. java用UDP实现网络编程代码实现:运行代码:启动多个客户端别人能否使用?实现翻译功能 一. 网络编程套接字 网络编程套接字, 就是指操作系统提…

linux 部署Ollama本地大模型

简介 llama 是一个大模型的管理框架&#xff0c;其作用类似于 Docker&#xff1a;如果将每一个标准化的大模型视为“镜像”&#xff0c;那么 Ollama 就能够通过一行命令快速拉取并运行这些大模型。然而&#xff0c;Ollama 本身是基于命令行的服务&#xff0c;所以为了方便我们…

足底筋膜炎怎么治

足底筋膜炎是一种常见的足部疾病&#xff0c;其主要症状及治疗方法如下&#xff1a; 一、症状 1、‌疼痛‌&#xff1a;足底筋膜炎最典型的症状是足跟或足底靠近足跟处的疼痛。这种疼痛在晨起或长时间休息后初次站立时尤为明显&#xff0c;但行走一段时间后可能会逐渐缓解。 …

超级兔子and这三款数据恢复软件,我的数据守护神!!

在数字化的时代&#xff0c;数据丢失已经成为了一个令人头疼的问题。无论是误删重要文件&#xff0c;还是硬盘出现故障&#xff0c;数据的丢失都可能带来不可估量的损失&#xff1b;幸运的是&#xff0c;有了超级兔子这这三款数据恢复软件这样的工具&#xff0c;让数据找回变得…

AI基础 L1 Introduction to Artificial Intelligence

什么是AI Chinese Room Thought Experiment 关于“强人工智能”的观点&#xff0c;即认为只要一个系统在行为上表现得像有意识&#xff0c;那么它就真的具有理解能力。 实验内容如下&#xff1a; 假设有一个不懂中文的英语说话者被关在一个房间里。房间里有一本用英文写的中…

【C++】list类:模拟实现(适合新手的手撕list)

提示&#xff1a;在开始模拟实现list前&#xff0c;最好先熟悉下list相关接口&#xff1a; 【C】容器list常用接口详解-CSDN博客https://blog.csdn.net/2301_80555259/article/details/141756824?spm1001.2014.3001.5501 目录 一.基本结构 二.构造函数 三.析构函数 四.迭代…

拍卖新纪元:Spring Boot赋能在线拍卖解决方案

需求分析 1.1技术可行性&#xff1a;技术背景 在线拍卖系统是在Windows操作系统中进行开发运用的&#xff0c;而且目前PC机的各项性能已经可以胜任普通网站的web服务器。系统开发所使用的技术也都是自身所具有的&#xff0c;也是当下广泛应用的技术之一。 系统的开发环境和配置…

ant mobile design组件库的PickerView组件不能滑动

问题 PickerView组件在开发环境可滑动&#xff0c;在测试环境不可滑动 正常开发环境是这样正常显示&#xff0c;并且可滑动的 发到测试环境后&#xff0c;变成了这样&#xff0c;并且只有中间那列可滑动&#xff0c;两边的都不能滑动&#xff0c;而且还会报警告 封装的组件…

修改服务器DNS解析及修改自动对时时区

修改服务器DNS解析&#xff1a; 1、搜索一下当地的DNS服务器的地址 2、登录服务器&#xff0c;执行 vim /etc/resolv.conf文件&#xff0c;在nameserver字段后填写DNS服务的地址 3、chattr i /etc/resolv.conf 加上不可修改权限&#xff0c;防止重启DNS被修改 修改自动对时…

jmeter压力测试,通过LLM利用RAG实现知识库问答,NEO4J部署,GraphRAG以知识图谱在查询时增强提示实现更准确的知识库问答(9/7)

前言 这周也是杂七杂八的一天&#xff08;高情商&#xff1a;我是一块砖&#xff0c;哪里需要往哪里搬&#xff09;&#xff0c;首先是接触了jemter这个压力测试工具&#xff0c;然后帮公司的AIGC项目编写使用手册和问答手册的第一版&#xff0c;并通过这个平台的智能体实现知识…

【LabVIEW学习篇 - 16】:文件操作

文章目录 CSV文件CSV写入CSV读取 TXT文件txt写入txt读取 INI文件INI文件写入INI文件读取 CSV文件 .csv (Comma-Separated Values&#xff09;是逗号分隔值文件格式&#xff0c;有时也称之为字符分隔值&#xff0c;因为分隔符也可以不是逗号(最常见的是逗号和制表符)&#xff0…

Spring01——Spring简介、Spring Framework架构、Spring核心概念、IOC入门案例、DI入门案例

为什么要学 spring技术是JavaEE开发必备技能&#xff0c;企业开发技术选型命中率>90%专业角度 简化开发&#xff1a;降低企业开发的复杂度框架整合&#xff1a;高效整合其他技术&#xff0c;提高开发与运行效率 学什么 简化开发 IOCAOP 事务处理 框架整合 MyBatis 怎…