欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

腾讯云 COS 上传文件--JAVA 版

最编程 2024-03-17 10:52:32
...

之前项目组用的是阿里云的oss存储文件,但是价格太贵了,后来比较了下,切换到了腾讯云的cos文件存储

0.项目使用的是SpringCloud框架

1.导入jar包,这里的jar包版本换成5.6.8以上的版本。

因为之前的jar包源码中对于腾讯云cos的appid解析有问题。

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

2.在相应的微服务的yml配置文件中增加腾讯云COS的配置

如下:

tencent:
  cos:
    app-id: 1301111110
    secret-id: AKAAAAAAAAAAAAAAAAAAAAAAAaA
    secret-key: bxbbbbbbbbbbbbbbbbbbbbbbbwVo
    bucket-name: shop-1301111110
    region-id: ap-shanghai
    base-url: https://shop-1301111110.cos.ap-shanghai.myqcloud.com

其中:
点击腾讯云控制台—密钥管理—云API密钥:
查看自己的appId和secretId,secretKey
在这里插入图片描述
在这里插入图片描述
bucket-name是自己的存储桶名称,region-id值得是所属地域
点击控制台—对象存储—存储桶列表即可看到。
在这里插入图片描述

base-url值得是你最终上传到cos上之后,返回的临时下载链接或者对象地址,有一个固定的url

3.java代码

1.配置文件yml中cos配置对应的类
BaseDO.java是我目前公司的基础代码,里面就一个toString()方法。可以忽略

package com.aa.bb.merops.config;

import com.aa.bb.commons.pojo.BaseDO;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 腾讯云cos上传文件配置
 */
@Data
@Component
@ConfigurationProperties(prefix = "tencent.cos")
public class TencentCosProperties4Picture extends BaseDO {

    private String appId;
    private String secretId;
    private String secretKey;
    private String bucketName;
    private String regionId;
    private String baseUrl;

}

2.编写config,获取CosClient
这个类,其实可以编写多个CosClient,这里是专门上传图片的CosClient

package com.aa.bb.merops.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.region.Region;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "tencent")
public class TencentCosConfig {

    public static final String COS_IMAGE = "image";

    @Autowired
    TencentCosProperties4Picture tencentCosProperties4Picture;

    @Bean
    @Qualifier(COS_IMAGE)
    @Primary
    public COSClient getCoSClient4Picture() {
        //初始化用户身份信息
        COSCredentials cosCredentials = new BasicCOSCredentials(tencentCosProperties4Picture.getSecretId(),tencentCosProperties4Picture.getSecretKey());
        //设置bucket区域,
        //clientConfig中包含了设置region
        ClientConfig clientConfig = new ClientConfig(new Region(tencentCosProperties4Picture.getRegionId()));
        //生成cos客户端
        COSClient cosClient = new COSClient(cosCredentials,clientConfig);
        return  cosClient;

    }


}

3.对应的上传文件的controller中,新增接口

	@Resource
    private TencentCosProperties4Picture tencentCosProperties4Picture;

    @Resource
    private TencentCosConfig tencentCosConfig;

    @Resource
    @Qualifier(TencentCosConfig.COS_IMAGE)
    private COSClient cosClient4Picture;

    @PostMapping("upload-file-tencent-cos")
    @ApiOperation("上传文件到腾讯云的cos中并返回url")
    public Result<String> getUploadFile2TencentCosUrl(@RequestParam("file") MultipartFile multipartFile) throws HuihuaException {
        VerifyUtils.notNull(multipartFile, "multipartFile", true);
        logger.info("getUploadFile2TencentCosUrl fucntion of FileController start !");

        File localFile = null;
        try {
            String originalFilename = multipartFile.getOriginalFilename();
            logger.info("fileName = {}",originalFilename);
            String[] filename = originalFilename.split("\\.");
            localFile=File.createTempFile(filename[0], filename[1]);
            multipartFile.transferTo(localFile);
            localFile.deleteOnExit();
        } catch (IOException e) {
            logger.info("MultipartFile transto file IOException ={}",e.getMessage());
            throw new HuihuaException(ResultCode.SYSTEM_ERROR.getCode(),ResultCode.SYSTEM_ERROR.getMsg());
        }

        if(localFile == null){
            throw new HuihuaException(ResultCode.MULTIPART_FILE_EOORO.getCode(),ResultCode.MULTIPART_FILE_EOORO.getMsg());
        }

        String key = TencentCosConfig.COS_IMAGE + "/" + new Date().getTime() + ".png";
        logger.info("key = {}", key);

        PutObjectRequest putObjectRequest =
                new PutObjectRequest(tencentCosProperties4Picture.getBucketName(), key, localFile);
        //设置存储类型 默认标准型
        putObjectRequest.setStorageClass(StorageClass.Standard);

        COSClient cosClient = tencentCosConfig.getCoSClient4Picture();

        try {
            PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);
            //putObjectResult 会返回etag
            String etag = putObjectResult.getETag();
            logger.info("eTag = {}", etag);
        } catch (CosServiceException e) {
            logger.error("CosServiceException ={}", e.getMessage());
            throw new CosServiceException(e.getMessage());
        } catch (CosClientException e) {
            logger.error("CosClientException ={}", e.getMessage());
            throw new CosClientException(e.getMessage());
        }
        cosClient.shutdown();
        String url = tencentCosProperties4Picture.getBaseUrl()+ "/" + key;
        return ResultUtils.successResult(url);

    }

返回的数据类型是

{
	“code”:"200",
	"msg":"success",
	"data":"上传成功后的文件url"
}

备注:


1.下载的jar包版本得注意,之前使用的是5.2.4的版本,会报错

please make sure bucket name must contain legal appid when appid is missing. example: music-1251122334

进入CosClient的源码中,搜索错误码,可以看到源码如下:

private String formatBucket(String bucketName, String appid) throws CosClientException {
        String parrtern;
        if (appid == null) {
            parrtern = ".*-(125|100)[0-9]{3,}$";
            if (Pattern.matches(parrtern, bucketName)) {
                return bucketName;
            } else {
                throw new CosClientException("please make sure bucket name must contain legal appid when appid is missing. example: music-1251122334");
            }
        } else {
            parrtern = "-" + appid;
            return bucketName.endsWith(parrtern) ? bucketName : bucketName + parrtern;
        }
    }

这个意思,存储桶的名称{name}-{appId},这个appId只能解析125,100开头的,但是目前新增 的存储桶都是130开头,所以升级下jar包版本即可。

2.上传文件成功后返回的url。
我的代码中是直接将上传图片的对象地址返回的,其实就是baseUrl/文件名称。
网上还有叫你写接口获取临时有效的url,供你下载的,这个看各人的需求了,我这边的需求是在小程序端展示,所以必须得要对象的地址。