腾讯对象存储COS入门使用-后端中转、前端直传两种方式

腾讯平台准备

1、登录腾讯云 - COS对象存储 - 创建存储桶

所属区域选择!

2、配置秘钥:

        用来后端连接云服务器

新建秘钥:

一、后端中转方式

使用

1、导入依赖

<!--腾讯云COS-->
    <dependency>
      <groupId>com.qcloud</groupId>
      <artifactId>cos_api</artifactId>
      <version>5.6.54</version>
    </dependency>

2、yml配置文件及配置类

application.yml

conf:
  cos:
    secretId: AKIDXyMgAYn6Z0sadadasdFtU6g9Y6ZwFVo
    secretKey: NdpZxzDSDSDDSDFDXrHqPtU8
    bucketName: bucket-1309444305
    region: ap-chengdu
    path: https://bucket-1309444305.cos.ap-chengdu.myqcloud.com
    folder: head

读取配置类:

@Component
@ConfigurationProperties(prefix = "conf.cos")
@Data
public class CosConfigProperties {
    /**
     * 账号ID
     */
    private String secretId;
    /**
     * 秘钥
     */
    private String secretKey;
    /**
     * 地区
     */
    private String region;
    /**
     * 桶名称
     */
    private String bucketName;
    /**
     * 路径
     */
    private String path;
    /**
     * 文件夹路径
     */
    private String folder;
    
    /**
     * 统一获取cos客户端
     */
    @Bean
    public COSClient cosClient(){
        //认证身份信息
        COSCredentials cred = new BasicCOSCredentials(this.secretId, this.secretKey);
        //区域
        Region region = new Region(this.region);
        //客户端配置
        ClientConfig clientConfig = new ClientConfig(region);
        //new一个客户端
        COSClient cosClient = new COSClient(cred, clientConfig);
        return cosClient;
    }
}

3、业务类配置

services

@Slf4j
@Service
public class ICosFileServiceImpl implements ICosFileService {
 
    @Resource
    private COSClient cosClient;
 
    @Resource
    private CosConfigProperties cosConfig;
 
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult upload(MultipartFile[] files) {

        String res = "";
        try {
            for (MultipartFile file : files) {
                String originalFileName = file.getOriginalFilename();
                // 获得文件流
                InputStream inputStream = null;
                inputStream = file.getInputStream();
 
                // 设置文件路径
                String filePath = getFilePath(originalFileName, cosConfig.getFolder());
                // 上传文件
                String bucketName = cosConfig.getBucketName();
                ObjectMetadata objectMetadata = new ObjectMetadata();
                objectMetadata.setContentLength(file.getSize());
                objectMetadata.setContentType(file.getContentType());
                PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, filePath, inputStream, objectMetadata);
                cosClient.putObject(putObjectRequest);
                cosClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
                String url = cosConfig.getPath() + "/" + filePath;
                res += url + ",";
            }
            String paths = res.substring(0, res.length() - 1);
            return AjaxResult.me().setResultObj(paths);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
//            cosClient.shutdown();  // 第二次上传报错
        }
        return AjaxResult.me();
    }
 
    @Override
    public AjaxResult delete(String fileName) {
        cosConfig.cosClient();
        // 文件桶内路径
        String filePath = getDelFilePath(fileName, cosConfig.getFolder());
        cosClient.deleteObject(cosConfig.getBucketName(), filePath);
        return AjaxResult.me();
    }
 
    /**
     * 生成文件路径
     * @param originalFileName 原始文件名称
     * @param folder 存储路径
     * @return
     */
    private String getFilePath(String originalFileName, String folder) {
        // 获取后缀名
        String fileType = originalFileName.substring(originalFileName.lastIndexOf("."));
        // 以文件后缀来存储在存储桶中生成文件夹方便管理
        String filePath = folder + "/";
        // 去除文件后缀 替换所有特殊字符
        String fileStr = StrUtils.removeSuffix(originalFileName, fileType).replaceAll("[^0-9a-zA-Z\\u4e00-\\u9fa5]", "_");
        filePath += new DateTime().toString("yyyyMMddHHmmss") + "_" + fileStr + fileType;
        log.info("filePath:" + filePath);
        return filePath;
    }
    /**
     * 生成文件路径
     * @param originalFileName 原始文件名称
     * @param folder 存储路径
     * @return
     */
    private String getDelFilePath(String originalFileName, String folder) {
        // 获取后缀名
        String fileType = originalFileName.substring(originalFileName.lastIndexOf("."));
        // 以文件后缀来存储在存储桶中生成文件夹方便管理
        String filePath = folder + "/";
        // 去除文件后缀 替换所有特殊字符
        String fileStr = StrUtils.removeSuffix(originalFileName, fileType).replaceAll("[^0-9a-zA-Z\\u4e00-\\u9fa5]", "_");
        filePath += fileStr + fileType;
        log.info("filePath:" + filePath);
        return filePath;
    }
}
public class StrUtils {
    /**
     * 去除文件后缀
     */
    public static String removeSuffix(String fileName, String suffix) {
        if (fileName == null || suffix == null) {
            return fileName;
        }
        if (fileName.endsWith(suffix)) {
            return fileName.substring(0, fileName.length() - suffix.length());
        }
        return fileName;
    }
}

4、接口配置

@RestController
@RequestMapping("/cos")
public class CosFileController {
 
    @Autowired
    private ICosFileService iCosFileService;
 
    @ApiOperation(value = "文件上传", httpMethod = "POST")
    @PostMapping("/upload")
    public AjaxResult upload(@RequestParam("files") MultipartFile[] files) {

        return iCosFileService.upload(files);
    }
 
    @ApiOperation(value = "文件删除", httpMethod = "POST")
    @PostMapping("/delete")
    public AjaxResult delete(@RequestParam("fileName") String fileName) {
        return iCosFileService.delete(fileName);
    }
}

5、测试上传多张图片

一张图片直接返回,多张返回一个逗号拼接

删除

二、前端直传方式

官网文档:对象存储 Web 端直传实践-实践教程-文档中心-腾讯云

签名接口文档:对象存储 生成预签名 URL-SDK 文档-文档中心-腾讯云

实现过程:

1、在前端选择文件,前端将后缀发送给服务端。

2、服务端根据后缀,生成带时间的随机 COS 文件路径,并计算对应的签名,返回 URL 和签名信息给前端。

3、前端使用 PUT 或 POST 请求,直传文件到 COS

使用

1、导入依赖

同上,注意版本!!

2、yml配置及资源类

同上

3、业务类配置

        在上面

@Slf4j
@Service
public class CosFileServiceImpl implements ICosFileService {

    @Resource
    private COSClient cosClient;

    @Resource
    private CosConfigProperties cosConfig;

    
    /**
     * 获取签名
     */
    @Override
    public URL getSign(String suffix) {
        COSClient cosclient = null;
        try {
            String secretId = cosConfig.getSecretId();
            String secretKey = cosConfig.getSecretKey();
            COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
            // 设置区域
            ClientConfig clientConfig = new ClientConfig(new Region(cosConfig.getRegion()));
            // cos 客户端
             cosclient = new COSClient(cred, clientConfig);

            String bucketName = cosConfig.getBucketName();
            String folder = cosConfig.getFolder();
            double ran = Math.random() * 100;
            long randomInt = Math.round(ran);
            String key = folder + "/" +System.currentTimeMillis() + randomInt + "." + suffix;
            Date expirationTime = new Date(System.currentTimeMillis() + 2 * 60 * 1000);
            // 填写本次请求的 header。Host 头部会自动补全,只需填入其他头部
            Map<String, String> headers = new HashMap<String,String>();
            // 填写本次请求的 params。
            Map<String, String> params = new HashMap<String,String>();
            URL url = cosclient.generatePresignedUrl(bucketName, key, expirationTime, HttpMethodName.PUT, headers, params);
            return url;
        } catch (Exception e) {
            throw new BusinessException("获取cos对象存储服务签名异常:" + e);
        }finally {
            assert cosclient != null;
            cosclient.shutdown();
        }
    }
    
}

4、接口配置

@RestController
@RequestMapping("/cos")
public class CosFileController {

    @Autowired
    private ICosFileService iCosFileService;
 
    @GetMapping("/getSignedUrl/{fileName}")
    public AjaxResult getSignedUrl(@PathVariable("fileName") String fileName ) {
        return AjaxResult.me().setResultObj(iCosFileService.getSign(fileName));
    }
}

5、测试上传

        先拿着文件名后缀名称向后端拿去签

        拿着后端返回的签名去上传腾讯cos服务器

!!!! 传输方式不对

        最终

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值