腾讯云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);
    }
相关推荐
木子Linux3 小时前
【Linux打怪升级记 | 问题01】安装Linux系统忘记设置时区怎么办?3个方法教你回到东八区
linux·运维·服务器·centos·云计算
不惑_4 小时前
小白入门 · 腾讯云轻量服务器部署 Hadoop 3.3.6
服务器·hadoop·腾讯云
CESS_Cloud1 天前
CESS 出席华盛顿区块链政策峰会:参与国家安全与数据隐私保护专题讨论
安全·阿里云·web3·去中心化·区块链
HaoHao_0101 天前
云消息队列 Kafka 版
分布式·阿里云·kafka·云计算·云服务器
sinat_307021532 天前
大数据技术与应用——大数据处理技术(一)(山东省大数据职称考试)
大数据·云计算
HaoHao_0102 天前
云消息队列 RabbitMQ 版
阿里云·云计算·云服务器
終不似少年遊*2 天前
云计算HCIP-OpenStack01
云原生·云计算·学习笔记·openstack·hcip·虚拟化
云计算DevOps-韩老师2 天前
【网络云计算】2024第51周-每日【2024/12/20】小测-理论-周测
云计算
jmoych2 天前
我在华为的安全日常
大数据·运维·网络·安全·华为·架构·云计算
HaoHao_0102 天前
应用实时监控服务ARMS
阿里云·云计算·云服务器