【代码可复用!】腾讯云 COS 对象存储管理与文件上传封装

使用前提

在开始使用 CosManagerFileManager 类之前,需要确保以下前提条件已满足:

1. 开通腾讯云对象存储(COS)服务

在这里插入图片描述

  • 注册腾讯云账号:如果您还没有腾讯云账号,可以前往 腾讯云官网 注册一个账号。
  • 开通对象存储(COS)服务:登录腾讯云控制台,进入 COS 服务开通页面,按照指引完成 COS 服务的开通。
  • 创建存储桶:在 COS 控制台中创建一个存储桶,用于存储上传的文件。创建时需要设置存储桶的名称、地域、访问权限等参数。
  • 获取 API 密钥:在腾讯云控制台的 API 密钥管理页面 中,获取您的 SecretIdSecretKey,这些密钥将用于初始化 COS 客户端。

2. 开通腾讯云数据万象(CI)服务

在这里插入图片描述

  • 开通数据万象(CI)服务:登录腾讯云控制台,进入 数据万象服务开通页面,按照指引完成 CI 服务的开通。
  • 关联存储桶:在数据万象控制台中,将您在 COS 中创建的存储桶关联到 CI 服务,以便使用图片处理、视频处理等功能。
  • 配置图片处理规则:在数据万象控制台中,您可以配置图片处理规则,例如图片压缩、裁剪、格式转换等。这些规则可以在上传图片时通过 PicOperations 类动态设置。

3. 配置 COS 客户端

在使用 CosManagerFileManager 类之前,您需要在项目中配置 COS 客户端,并在 Spring Boot 中注入相关依赖。以下是配置步骤:

3.1 配置 CosClientConfig

CosClientConfig 类用于存储 COS 客户端的配置信息,包括 SecretIdSecretKey、存储桶名称、访问域名等。

package cn.yam.sypicture.config;

import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.http.HttpProtocol;
import com.qcloud.cos.region.Region;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@ConfigurationProperties(prefix = "cos.client")
@Data
public class CosClientConfig {

    /**
     * 域名
     */
    private String host;

    /**
     * secretId
     */
    private String secretId;

    /**
     * 密钥(注意不要泄露)
     */
    private String secretKey;

    /**
     * 区域
     */
    private String region;

    /**
     * 桶名
     */
    private String bucket;

    @Bean
    public COSClient cosClient() {
        // 1 初始化用户身份信息(secretId, secretKey)。
        // SECRETID 和 SECRETKEY 请登录访问管理控制台 https://console.cloud.tencent.com/cam/capi 进行查看和管理
        COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
        // 2 设置 bucket 的地域, COS 地域的简称请参见 https://cloud.tencent.com/document/product/436/6224
        // clientConfig 中包含了设置 region, https(默认 http), 超时, 代理等 set 方法, 使用可参见源码或者常见问题 Java SDK 部分。
        ClientConfig clientConfig = new ClientConfig(new Region(region));
        // 这里建议设置使用 https 协议
        // 从 5.6.54 版本开始,默认使用了 https
        clientConfig.setHttpProtocol(HttpProtocol.https);
        // 3 生成 cos 客户端。
        return new COSClient(cred, clientConfig);
    }
}

3.2 配置 application.yml

在 Spring Boot 项目中,将腾讯云的相关配置信息写入 application.yml 文件中:
注意这部分内容注意切勿泄露,解决方案请看:https://blog.csdn.net/web2u/article/details/145445772?spm=1001.2014.3001.5502

tencent:
  cos:
    secretId: your-secret-id
    secretKey: your-secret-key
    bucket: your-bucket-name
    region: ap-chengdu # 存储桶所在地域
    host: https://your-bucket-name.cos.ap-chengdu.myqcloud.com # 存储桶访问域名

3.3 注入依赖

CosManagerFileManager 类中,通过 @Resource 注解注入 CosClientConfigCOSClient

@Resource
private CosClientConfig cosClientConfig;

@Resource
private COSClient cosClient;

4. 总结

使用 CosManagerFileManager 类的前提是开通腾讯云对象存储(COS)和数据万象(CI)服务,并完成相关配置。通过合理的设计和封装,您可以轻松实现文件的上传、下载、处理等功能,提升开发效率并降低维护成本。

希望本文的详细说明能帮助您顺利使用腾讯云 COS 和 CI 服务,并为您的项目提供高效稳定的文件管理能力。

腾讯云 COS 对象存储管理与文件上传封装

在现代 Web 应用中,对象存储(如腾讯云 COS)是存储和管理文件的重要工具。本文将介绍如何使用腾讯云 COS Java SDK 封装一个通用的对象存储管理类 CosManager 和文件上传类 FileManager,并通过代码示例展示其使用方法。

1. 引入依赖

首先,我们需要在项目中引入腾讯云 COS 的 Java SDK。在 Maven 项目中,可以通过以下方式引入依赖:

<dependency>
    <groupId>com.qcloud</groupId>
    <artifactId>cos_api</artifactId>
    <version>5.6.97</version>
</dependency>

2. CosManager 类设计

在这里插入图片描述

CosManager 类是对腾讯云 COS 服务的封装,提供上传、下载、删除对象的基本功能,并支持图片处理(如压缩、生成缩略图等)。

2.1 CosManager 类代码

package cn.yam.sypicture.manager;

import javax.annotation.Resource;

import cn.hutool.core.io.FileUtil;
import cn.yam.sypicture.config.CosClientConfig;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.model.COSObject;
import com.qcloud.cos.model.GetObjectRequest;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.model.PutObjectResult;
import com.qcloud.cos.model.ciModel.persistence.PicOperations;
import org.springframework.stereotype.Component;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

@Component
public class CosManager {

    @Resource
    private CosClientConfig cosClientConfig;

    @Resource
    private COSClient cosClient;

    /**
     * 上传对象
     *
     * @param key  唯一键
     * @param file 文件
     */
    public PutObjectResult putObject(String key, File file) {
        PutObjectRequest putObjectRequest = new PutObjectRequest(cosClientConfig.getBucket(), key, file);
        return cosClient.putObject(putObjectRequest);
    }

    /**
     * 下载对象
     *
     * @param key 唯一键
     */
    public COSObject getObject(String key) {
        GetObjectRequest getObjectRequest = new GetObjectRequest(cosClientConfig.getBucket(), key);
        return cosClient.getObject(getObjectRequest);
    }

    /**
     * 上传对象(附带图片信息)
     *
     * @param key  唯一键
     * @param file 文件
     */
    public PutObjectResult putPictureObject(String key, File file) {
        PutObjectRequest putObjectRequest = new PutObjectRequest(cosClientConfig.getBucket(), key, file);
        // 对图片进行处理(获取基本信息也被视作为一种图片的处理)
        PicOperations picOperations = new PicOperations();
        // 1 表示返回原图信息
        picOperations.setIsPicInfo(1);
        // 图片处理规则列表
        List<PicOperations.Rule> rules = new ArrayList<>();
        // 1. 图片压缩(转成 webp 格式)
        String webpKey = FileUtil.mainName(key) + ".webp";
        PicOperations.Rule compressRule = new PicOperations.Rule();
        compressRule.setFileId(webpKey);
        compressRule.setBucket(cosClientConfig.getBucket());
        compressRule.setRule("imageMogr2/format/webp");
        rules.add(compressRule);
        // 2. 缩略图处理,仅对 > 20 KB 的图片生成缩略图
        if (file.length() > 2 * 1024) {
            PicOperations.Rule thumbnailRule = new PicOperations.Rule();
            // 拼接缩略图的路径
            String thumbnailKey = FileUtil.mainName(key) + "_thumbnail." + FileUtil.getSuffix(key);
            thumbnailRule.setFileId(thumbnailKey);
            thumbnailRule.setBucket(cosClientConfig.getBucket());
            // 缩放规则 /thumbnail/<Width>x<Height>>(如果大于原图宽高,则不处理)
            thumbnailRule.setRule(String.format("imageMogr2/thumbnail/%sx%s>", 256, 256));
            rules.add(thumbnailRule);
        }
        // 构造处理参数
        picOperations.setRules(rules);
        putObjectRequest.setPicOperations(picOperations);
        return cosClient.putObject(putObjectRequest);
    }

    /**
     * 删除对象
     *
     * @param key 唯一键
     */
    public void deleteObject(String key) {
        cosClient.deleteObject(cosClientConfig.getBucket(), key);
    }
}

2.2 功能解析

  • 上传对象putObject 方法用于上传文件到 COS,接受文件的唯一键和文件对象作为参数。
  • 下载对象getObject 方法用于从 COS 下载文件,返回一个 COSObject 对象。
  • 上传图片并处理putPictureObject 方法在上传图片时,自动进行图片压缩和生成缩略图。它使用 PicOperations 类来设置图片处理规则。
  • 删除对象deleteObject 方法用于删除 COS 中的文件。

3. FileManager 类设计

FileManager 类封装了文件上传的逻辑,包括文件校验、文件上传、返回上传结果等功能。它依赖于 CosManager 类来完成实际的文件上传操作。

3.1 FileManager 类代码

package cn.yam.sypicture.manager;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;
import cn.yam.sypicture.config.CosClientConfig;
import cn.yam.sypicture.constant.Constant;
import cn.yam.sypicture.exception.BusinessException;
import cn.yam.sypicture.exception.ErrorCode;
import cn.yam.sypicture.exception.ThrowUtils;
import cn.yam.sypicture.model.dto.file.UploadPictureResult;
import com.qcloud.cos.model.PutObjectResult;
import com.qcloud.cos.model.ciModel.persistence.ImageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

@Slf4j
public class FileManager {

    @Resource
    private CosClientConfig cosClientConfig;

    @Resource
    private CosManager cosManager;

    public UploadPictureResult uploadPicture(MultipartFile multipartFile, String uploadPathPrefix) {
        // 校验图片
        validPicture(multipartFile);
        // 图片上传地址
        String uuid = RandomUtil.randomString(16);
        String originalFilename = multipartFile.getOriginalFilename();
        // 自己拼接文件上传路径,而不是使用原始文件名称,可以增强安全性
        String uploadFilename = String.format("%s_%s.%s", DateUtil.formatDate(new Date()), uuid,
                FileUtil.getSuffix(originalFilename));
        String uploadPath = String.format("/%s/%s", uploadPathPrefix, uploadFilename);
        File file = null;
        try {
            // 上传文件
            file = File.createTempFile(uploadPath, null);
            multipartFile.transferTo(file);
            PutObjectResult putObjectResult = cosManager.putPictureObject(uploadPath, file);
            // 获取图片信息对象
            ImageInfo imageInfo = putObjectResult.getCiUploadResult().getOriginalInfo().getImageInfo();
            // 计算宽高
            int picWidth = imageInfo.getWidth();
            int picHeight = imageInfo.getHeight();
            double picScale = NumberUtil.round(picWidth * 1.0 / picHeight, 2).doubleValue();
            // 封装返回结果
            UploadPictureResult uploadPictureResult = new UploadPictureResult();
            uploadPictureResult.setUrl(cosClientConfig.getHost() + "/" + uploadPath);
            uploadPictureResult.setPicName(FileUtil.mainName(originalFilename));
            uploadPictureResult.setPicSize(FileUtil.size(file));
            uploadPictureResult.setPicWidth(picWidth);
            uploadPictureResult.setPicHeight(picHeight);
            uploadPictureResult.setPicScale(picScale);
            uploadPictureResult.setPicFormat(imageInfo.getFormat());
            // 返回可访问的地址
            return uploadPictureResult;
        } catch (Exception e) {
            log.error("图片上传到对象存储失败", e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "上传失败");
        } finally {
            // 临时文件清理
            this.deleteTempFile(file);
        }
    }

    /**
     * 校验文件
     *
     * @param multipartFile
     */
    private void validPicture(MultipartFile multipartFile) {
        ThrowUtils.throwIf(multipartFile == null, ErrorCode.PARAMS_ERROR, "文件不能为空");
        // 1. 校验文件大小
        long fileSize = multipartFile.getSize();

        ThrowUtils.throwIf(fileSize > 2 * Constant.ONE_M, ErrorCode.PARAMS_ERROR, "文件大小不能超过 2MB");
        // 2. 校验文件后缀
        String fileSuffix = FileUtil.getSuffix(multipartFile.getOriginalFilename());
        // 允许上传的文件后缀列表(或者集合)
        final List<String> ALLOW_FORMAT_LIST = Arrays.asList("jpeg", "png", "jpg", "webp");
        ThrowUtils.throwIf(!ALLOW_FORMAT_LIST.contains(fileSuffix), ErrorCode.PARAMS_ERROR, "文件类型错误");
    }

    /**
     * 清理临时文件
     *
     * @param file
     */
    public void deleteTempFile(File file) {
        if (file == null) {
            return;
        }
        // 删除临时文件
        boolean deleteResult = file.delete();
        if (!deleteResult) {
            log.error("file delete error, filepath = {}", file.getAbsolutePath());
        }
    }
}

3.2 功能解析

  • 上传图片uploadPicture 方法接受 MultipartFile 和上传路径前缀作为参数,完成文件上传并返回上传结果。
  • 文件校验validPicture 方法用于校验文件的大小和格式,确保上传的文件符合要求。
  • 临时文件清理deleteTempFile 方法用于清理上传过程中生成的临时文件。

4. 总结

通过 CosManagerFileManager 两个类的封装,我们实现了对腾讯云 COS 服务的统一管理,简化了文件上传和处理的流程。这种设计不仅提高了代码的复用性,还增强了系统的可维护性和安全性。

希望本文的代码示例和设计思路能为你在使用腾讯云 COS 时提供参考和帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值