腾讯云COS和阿里云OSS在Springboot中的使用

news2024/11/24 20:26:27

引言:之前本来是用OSS做存储的,但是上线小程序发现OSS貌似消费比COS多一些,所以之前做了技术搬迁,最近想起,打算做个笔记记录一下,这里省去在阿里云注册OSS或腾讯云中注册COS应用了。

一、OSS

1、配置yml
qupai:
  alioss:
    endpoint: ${qupai.alioss.endpoint}
    access-key-id: ${qupai.alioss.access-key-id}
    access-key-secret: ${qupai.alioss.access-key-secret}
    bucket-name: ${qupai.alioss.bucket-name}

2、编写配置类读取yml配置
@Component
@ConfigurationProperties(prefix = "qupai.alioss")
@Data
public class AliOssProperties {

    private String endpoint;
    private String accessKeyId;
    private String accessKeySecret;
    private String bucketName;

}

3、编写COS工具类
@Data
@AllArgsConstructor
@Slf4j
public class AliOssUtil {

    private String endpoint;
    private String accessKeyId;
    private String accessKeySecret;
    private String bucketName;

    /**
     * 文件上传
     *
     * @param bytes
     * @param objectName
     * @return
     */
    public String upload(byte[] bytes, String objectName) {

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        try {
            // 创建PutObject请求。
            ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(bytes));
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }

        //文件访问路径规则 https://BucketName.Endpoint/ObjectName
        StringBuilder stringBuilder = new StringBuilder("https://");
        stringBuilder
                .append(bucketName)
                .append(".")
                .append(endpoint)
                .append("/")
                .append(objectName);

        log.info("文件上传到:{}", stringBuilder.toString());

        return stringBuilder.toString();
    }
}

4、声明配置类在程序开始时交给bean对象注入
/**
 * 配置类,用于创建AliOssUtils对象
 */
@Configuration//声明配置类
@Slf4j
public class OssConfiguration {
    @Bean//程序开始时交给bean对象注入
    @ConditionalOnMissingBean//保证spring容器里面只有一个utils对象(当没有这个bean对象再去创建,有就没必要去创建了)
    public AliOssUtil aliOssUtil(AliOssProperties aliOssProperties){
        log.info("开始创建阿里云文件上传工具类对象: {}",aliOssProperties);
        return new AliOssUtil(aliOssProperties.getEndpoint(),
                aliOssProperties.getAccessKeyId(),
                aliOssProperties.getAccessKeySecret(),
                aliOssProperties.getBucketName());
    }
}

5、在接口中使用
/**
 * 通用接口
 */
@RestController("adminCommonController")
@RequestMapping("/admin/common")
@Tag(name = "通用接口")
@Slf4j
public class CommonController {
    @Resource
    private AliOssUtil aliOssUtil;

    /**
     * 文件上传
     * @param file
     * @return
     */
    @PostMapping("/upload")
    @Operation(summary="文件上传")
    public Result<String> upload(MultipartFile file) {
        log.info("上传文件:{}", file);
        //file.getBytes(),file对象转成的一个数组,objectName文件名通过uuid来生成
        try {
            //原始文件名
            String originalFilename = file.getOriginalFilename();
            //截取元素文件名的后缀,dfdfdf.png
            String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
            //构造新的文件名称
            String objectName=UUID.randomUUID().toString()+extension;
            //文件的请求路径
            String filePath = aliOssUtil.upload(file.getBytes(), objectName);
            return Result.success(filePath);
        } catch (IOException e) {
            log.error("文件上传失败: {}", e);
        }

        return Result.error(MessageConstant.UPLOAD_FAILED);
    }
}

二、COS

1、配置yml
quick:
  tencentcos:
    appid: ${quick.tencentcos.appid}
    secret-id: ${quick.tencentcos.secret-id}
    secret-key: ${quick.tencentcos.secret-key}
    bucket-name: ${quick.tencentcos.bucket-name}
    cos-path: ${quick.tencentcos.cos-path}
    region: ${quick.tencentcos.region}

 

2、编写配置类读取yml配置

/*
 * @读取yml配置
 */
@Component
@Data
@ConfigurationProperties(prefix = "quick.tencentcos")
public class TencentCosProperties {

    private String appid;
    private String secretId;
    private String secretKey;
    private String bucketName;
    private String cosPath;
    private String region;

}

3、编写COS工具类
@Data
@AllArgsConstructor
@Slf4j
public class TencentCosUtil {
    // 腾讯云cos 配置信息
    private String appid;
    private String secretId;
    private String secretKey;
    private String bucketName;
    private String cosPath;
    private String region;

    /**
     * 1.调用静态方法getCosClient()就会获得COSClient实例
     * 2.本方法根据永久密钥初始化 COSClient的,官方是不推荐,官方推荐使用临时密钥,是可以限制密钥使用权限,创建cred时有些区别
     *
     * @return COSClient实例
     */
    public COSClient getCosClient() {
        // 1 初始化用户身份信息(secretId, secretKey)
        COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
        // 2.1 设置存储桶的地域(上文获得)
        Region region_new = new Region(region);
        ClientConfig clientConfig = new ClientConfig(region_new);
        // 2.2 使用https协议传输
        clientConfig.setHttpProtocol(HttpProtocol.https);
        // 3 生成 cos 客户端
        // 返回COS客户端
        return new COSClient(cred, clientConfig);
    }

    /**
     * 上传文件
     *
     * @param file 上传的文件
     * @return 返回文件的url
     */
    public String upLoadFile(MultipartFile file) {
        try {
            // 获取上传的文件的输入流
            InputStream inputStream = file.getInputStream();

            // 避免文件覆盖,获取文件的原始名称,如123.jpg,然后通过截取获得文件的后缀,也就是文件的类型
            String originalFilename = file.getOriginalFilename();
            // 获取文件的类型
            String fileType = originalFilename.substring(originalFilename.lastIndexOf("."));
            // 使用UUID工具  创建唯一名称,放置文件重名被覆盖,在拼接上上命令获取的文件类型
            String fileName = UUID.randomUUID().toString() + fileType;
            // 指定文件上传到 COS 上的路径,即对象键最终文件会传到存储桶名字中的images文件夹下的fileName名字
            String key = "/images/" + fileName;
            // 创建上传Object的Metadata
            ObjectMetadata objectMetadata = new ObjectMetadata();
            // - 使用输入流存储,需要设置请求长度
            objectMetadata.setContentLength(inputStream.available());
            // - 设置缓存
            objectMetadata.setCacheControl("no-cache");
            // - 设置Content-Type
            objectMetadata.setContentType(fileType);
            // 上传文件
            PutObjectResult putResult = getCosClient().putObject(bucketName, key, inputStream, objectMetadata);
            // 创建文件的网络访问路径
            String url = cosPath + key;
            // 关闭 cosClient,并释放 HTTP 连接的后台管理线程
            getCosClient().shutdown();
            return url;

        } catch (Exception e) {
            e.printStackTrace();
            // 发生IO异常、COS连接异常等,返回空
            return null;
        }
    }


}

4、声明配置类在程序开始时交给bean对象注入
/**
 * 配置类,用于创建AliOssUtils对象
 */
@Configuration//声明配置类
@Slf4j
public class CosConfiguration {
    @Bean//程序开始时交给bean对象注入
    @ConditionalOnMissingBean//保证spring容器里面只有一个utils对象(当没有这个bean对象再去创建,有就没必要去创建了)
    public TencentCosUtil tencentCosUtil(TencentCosProperties tencentCosProperties){
        log.info("开始创建腾讯云文件上传工具类对象: {}",tencentCosProperties);
        return new TencentCosUtil(tencentCosProperties.getAppid(),
                tencentCosProperties.getSecretId(),
                tencentCosProperties.getSecretKey(),
                tencentCosProperties.getBucketName(),
                tencentCosProperties.getCosPath(),
                tencentCosProperties.getRegion());
    }
}

5、在接口中使用
    @Resource
    private TencentCosUtil tencentCosUtil;

    /**
     * 文件上传
     */
    @PostMapping("/upload")
    //@ApiOperation("文件上传")
    @Operation(summary = "文件上传")
    public Result<String> upload(MultipartFile file) {
        log.info("上传文件:{}", file);
        log.info("正在上传,文件名{}",file.getOriginalFilename());
        String url = tencentCosUtil.upLoadFile(file);
        log.info("文件的Url:{}",url);
        return Result.success(url);
    }

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

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

相关文章

Linux 网络设备驱动

一.网络设备驱动框架 接收 将报文从设备驱动接受并送入协议栈 老API netif_if 编写网络设备驱动 步骤 1.注册一个网络设备 2.填充net_device_ops结构体 3.编写接收发送函数 // SPDX-License-Identifier: GPL-2.0-only /** This module emits "Hello, world"…

IOS 02 SnapKit 纯代码开发

SnapKit是一个Swift语言写的自动布局框架&#xff0c;可以运行到iOS&#xff0c;Mac系统上&#xff1b;OC版本的框架是Masonry&#xff0c;都是出自同一个团队。 用这个框架的目的是&#xff0c;用起来比系统自带的API方便&#xff0c;他内部也是对系统API进行了封装。 为什么…

房产中介小程序

本文来自&#xff1a;ThinkPHPFastAdmin房产中介小程序 - 源码1688 应用介绍 产中介小程序是一款基于ThinkPHPFastAdmin开发的原生微信小程序&#xff0c;为房地产中介提供房源管理、发布、报备客户、跟踪客户以及营销推广获客等服务的系统。 前端演示&#xff1a; 后台演示&am…

HarmonyOS应用开发者基础认证(三)

1、针对包含文本元素的组件&#xff0c;例如Text、Button、TextInput等&#xff0c;可以使用下列哪些属性&#xff1a;&#xff08;全选&#xff09; 答案&#xff1a; fontColor fontFamily fontSize fontWeight fontStyle 分析&#xff1a; 2、关于Tabs组件和TabContent组件&…

【高效笔记与整理的艺术】

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

通过jmeter对websocket后台做压测

后台使用java程序&#xff0c;通过springboot集成的stomp协议暴露websocket接口&#xff0c;所以下文测试过程会有特定的stomp报文&#xff0c;无需在意&#xff0c;关注流程即可 本次测试使用jmeter模拟大量用户接收群消息的场景&#xff0c;可覆盖连接数以及消息并发的压测 一…

CentOS7.6 RabbitMQ消息队列集群部署——实施方案

1、前期环境准备&#xff08;每个主机都配置&#xff09; 1.准备三台主机 IP地址主机名内存大小192.168.200.10 rabbitmq1 2G192.168.200.11rabbitmq22G192.168.200.55rabbitmq32G 2. 设置主机名 hostnamectl set-hostname 主机名suexit Ctrlr 3. 设置IP地址然后重启网卡 …

深度学习与图像修复:ADetailer插件在Stable Diffusion中的应用

文章目录 引言ADetailer插件介绍插件安装常用模型控制提示词参数配置参数详解 实践建议 示例插件的对比&#xff1a;1. ADetailer插件2. Photoshop插件&#xff08;如Nik Collection&#xff09;3. GIMP插件&#xff08;如GMIC&#xff09;4. Affinity Photo插件 结语 引言 无…

【物联网】(蓝牙篇)微信小程序ios如何自动打开蓝牙

微信小程序打开蓝牙的便捷之道——微信小程序ios如何自动打开蓝牙 随着智能手机蓝牙技术和物联网产品的普及&#xff0c;很多人在使用微信小程序时&#xff0c;都希望能够更便捷地打开蓝牙功能。 在iOS系统上&#xff0c;由于其封闭性和权限控制严格&#xff0c;使得自动打开蓝…

OpenGL ES->GLSurfaceView进行点、线段、三角形等基本图元的绘制

GLSurfaceView代码见OpenGL ES-&#xff1e;顶点着色器和片段着色器代码&#xff0c;只修改顶点数组&#xff0c;片段着色器的颜色&#xff0c;和绘制方式进行不同图元绘制 绘制点 GL_POINTS方式 // 顶点数据 val vertices floatArrayOf(0.8f, -0.8f, 0.0f,-0.8f, -0.8f, 0…

Python大数据分析——SVM模型(支持向量机)

Python大数据分析——SVM模型&#xff08;支持向量机&#xff09; 认知模型介绍距离计算模型思想目标函数函数与几何间隔 线性可分SVM模型目标函数函数代码 非线性可分SVM模型目标函数函数代码 示例手写体字母识别森林火灾面积预测 认知模型 介绍 超平面的理解&#xff1a;在…

Stable Diffusion绘画 | 进阶语法

控制提示词生效时间 使用格式1&#xff1a;[提示词:0-1数值] 举例&#xff1a;forest,lots of trees and stones,[flowers:0.7] 其中 [flowers:0.7] 表示整体画面采样值达到70%的进程以后&#xff0c;才开始计算花的采样。 因此&#xff0c;花的数量仅仅只跑了末段的30%&am…

LeetCode之回溯

1.全排列 1.1 题目 1.2 题解 LeetCode 力扣官方题解 1.3 代码 class Solution {public List<List<Integer>> permute(int[] nums) {// 创建一个空的列表 res&#xff0c;用于存储所有的排列结果List<List<Integer>> res new ArrayList<>();/…

C++入门基础:数据类型与条件判断语句

数据类型 基础数据类型 整型&#xff08;Integral Types&#xff09; int&#xff1a;基本的整型&#xff0c;大小依赖于编译器和平台&#xff0c;通常是32位或64位。 short&#xff1a;短整型&#xff0c;通常是16位。 long&#xff1a;长整型&#xff0c;大小依赖于编译…

本地部署Code Llama大模型结合Text generation Web UI远程运行LLM

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

pdf拆分成一页一页,怎么操作?pdf拆分的好用方法

pdf拆分成一页一页&#xff0c;怎么操作&#xff1f;PDF文件的拆分通常涉及到以下几个常见场景和需求&#xff1a;首先&#xff0c;PDF文件可能包含大量的页面&#xff0c;例如数百页的电子书或详尽的技术手册。在某些情况下&#xff0c;用户可能只需要处理其中的几页或者想要单…

揭秘!亚马逊与速卖通自养号测评:必备资源与技术要点

面对测评服务商的种种承诺&#xff0c;其真实性往往难以验证&#xff0c;而在像Facebook这样的社交平台上自行寻找测评资源&#xff0c;也显得相当困难和不切实际。随着产品即将上架&#xff0c;寻找一个可靠的测评服务似乎并不那么容易。因此&#xff0c;对于亚马逊等跨境平台…

运动耳机哪个品牌好用?五款质量一流品牌推荐!

运动耳机无疑是运动爱好者的绝佳伴侣&#xff0c;让每一次挥汗如雨的瞬间都伴随着无与伦比的音乐盛宴与舒适的佩戴感受。特别是对于跑步爱好者而言&#xff0c;一款优秀的运动耳机更是不可或缺的装备。然而&#xff0c;市场上的运动耳机种类繁多&#xff0c;质量也千差万别&…

Mirror学习笔记(五)概念指南

文章目录 一、Authority(权限)二、IDs(身份编号)三、Attributes(属性)四、Time Synchronization(同步时间)五、Data types(数据类型)六、Serialization(序列化)七、Synchronization(同步)八、Communications(通讯)九、GameObject(游戏对象) 顶层脚本API: Mirror是一个高级网络库…

Qt信号与槽-思维导图-学习笔记

Qt 信号与槽 Qt 信号与槽机制 基本概念 信号与槽机制&#xff1a;Qt 编程的基础与创新&#xff0c;使得处理界面组件交互操作更加直观和简单 信号&#xff08;Signal&#xff09;&#xff1a;在特定情况下被发射的事件&#xff0c;如按钮点击的 clicked() 信号、组合框项变化…