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

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

一、OSS

1、配置yml
java 复制代码
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配置
java 复制代码
@Component
@ConfigurationProperties(prefix = "qupai.alioss")
@Data
public class AliOssProperties {

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

}
3、编写COS工具类
java 复制代码
@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对象注入
java 复制代码
/**
 * 配置类,用于创建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、在接口中使用
java 复制代码
/**
 * 通用接口
 */
@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配置
java 复制代码
/*
 * @读取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工具类
java 复制代码
@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对象注入
java 复制代码
/**
 * 配置类,用于创建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、在接口中使用
java 复制代码
    @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);
    }
相关推荐
小鱼小鱼.oO27 分钟前
阿里云服务器安装nginx并配置前端资源路径(前后端部署到一台服务器并成功访问)
服务器·nginx·阿里云
avoidaily4 小时前
使用Node.js分片上传大文件到阿里云OSS
阿里云·node.js·云计算
Elastic 中国社区官方博客8 小时前
Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合
大数据·人工智能·elasticsearch·搜索引擎·云计算·全文检索·aws
agenIT9 小时前
腾讯云 Python3.12.8 通过yum安装 并设置为默认版本
云计算·腾讯云
Johny_Zhao9 小时前
阿里云数据库Inventory Hint技术分析
linux·mysql·信息安全·云计算·系统运维
容器魔方9 小时前
议程一览 | KubeCon China 2025 华为云精彩前瞻
云原生·容器·云计算
FBI HackerHarry浩9 小时前
云计算 Linux Rocky day05【rpm、yum、history、date、du、zip、ln】
linux·运维·云计算·腾讯云
阿杆12 小时前
大故障,阿里云核心域名疑似被劫持
云计算·阿里巴巴
国际云17 小时前
腾讯云国际版和国内版账户通用吗?一样吗?为什么?
大数据·运维·阿里云·云计算
ZStack开发者社区18 小时前
全球化2.0|云轴科技ZStack助力香港服务机构VMware替代
运维·云计算·政务