腾讯云产品系列(一)COS对象存储上传

前言

作者标签:自己选择的路,没有什么后悔的。

本文章主要介绍,腾讯云COS对象存储上传文件实例并进行封装。


一、COS对象存储是什么?

COS对象存储简单来说就是为大家上传文件,处理文件的,开发上传文件到本地会有带宽,占用物理内存等种种限制,所以单独抽出来,进行存储,单独存放到公共资源。

二、COS对象存储能做什么?

1.图文介绍流程

COS 用于数据处理(来自腾讯云官网)

对象存储流程

COS 用于内容分发(来自腾讯云官网)

内容分发

2.简单介绍

对象存储(Cloud Object Storage,COS)是一种存储海量文件的分布式存储服务,用户可通过网络随时存储和查看数据。腾讯云 COS 使所有用户都能使用具备高扩展性、低成本、可靠和安全的数据存储服务。

简单来说,就是可以为大家上传文件提供公共接口,上传到线上资源库,通过腾讯云进行内容分发,用户进行访问。

三、COS对象存储怎么使用?

腾讯云官方文档:https://cloud.tencent.com/document/product/436/38484

1.准备工作

初次使用对象存储 COS,建议您先了解以下基本概念:

  1. 存储桶(bucket):是对象的载体,可理解为存放对象的“容器”。
  2. 对象(Object):是对象存储的基本单元,可理解为任何格式类型的数据,例如图片、文档和音视频文件等。
  3. 地域(Region):是腾讯云托管机房的分布地区,对象存储 COS 的数据存放在这些地域的存储桶中。

2.本文引用javaSDK版本示例

  • 安装sdk依赖
  • 代码如下(示例):
		<!--腾讯云COS-->
		     <dependency>
		         <groupId>com.tencentcloudapi</groupId>
		         <artifactId>tencentcloud-sdk-java</artifactId>
		         <version>3.0.1</version>
		     </dependency>
		     <dependency>
		         <groupId>com.qcloud</groupId>
		         <artifactId>cos_api</artifactId>
		         <version>5.6.8</version>
		     </dependency>
		<!--腾讯云COS-->
  • 封装上传配置配置类
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 com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.MimeTypeUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import org.apache.commons.io.FilenameUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * @program: cos
 * @description: 存储桶信息配置类
 * @author: Sun
 * @create: 2020-11-19 15:32
 **/

public class TencentCosConfig {
    //存储桶ID
    public static final String COS_APP_ID = "YOUR APPID";
    //存储桶名称
    public static final String COS_BUCKET_NAME = "YOUR BUCKET_NAME";
    //存储桶region名称
    public static final String COS_REGION_NAME = "YOUR REGION_NAME";
    //存储桶密钥id
    public static final String COS_SECRET_ID = "YOUR SECRET_ID";
    //存储桶密钥ley
    public static final String COS_SECRET_KEY = "YOUR SECRET_KEY";
    //存储桶对象Key 前缀
    public static final String COS_RESORCE_PATH="/XXX/xxx/";
    //存储桶访问域名
    public static final String COS_DOMAIN_URL="YOUR DOMAIN_URL";




    /**
     *
     * 方法名称:获取存储桶客户端
     * @return : com.qcloud.cos.COSClient
     * @author : Sun
     * @date : 2020/11/19
     */
    public static COSClient getCosClient(){
        // 1 初始化用户身份信息(secretId, secretKey)。
        COSCredentials cred = new BasicCOSCredentials(COS_SECRET_ID, COS_SECRET_KEY);
        // 2 设置 bucket 的区域, COS 地域的简称请参照 https://cloud.tencent.com/document/product/436/6224
        // clientConfig 中包含了设置 region, https(默认 http), 超时, 代理等 set 方法, 使用可参见源码或者常见问题 Java SDK 部分。
        Region region = new Region(COS_REGION_NAME);
        ClientConfig clientConfig = new ClientConfig(region);
        // 3 生成 cos 客户端。
        return new COSClient(cred, clientConfig);
    }

    /**
     *
     * 方法名称:获取对象键(Key)是对象在存储桶中的唯一标识。
     *
     * 功能描述:
     * 〈
     *   获取对象键(Key)是对象在存储桶中的唯一标识。
     *   桶内没有文件架的概念
     *   例如,在对象的访问域名
     *   https://examplebucket-1250000000.cos.ap-guangzhou.myqcloud.com/images/picture.jpg 中,
     *   对象键为 images/picture.jpg,
     *   对象键就是访问域名后面的所有路径URL  并且唯一
     *  〉
     *
     * @param file 1
     * @param path 2
     * @return : java.lang.String
     * @author : Sun
     * @date : 2020/11/19
     */
    public static String getCosFileKey(MultipartFile file,String path){
        if (StringUtils.isNotNull(path)){
            //模拟路径:/campus/res/sysimg/ + circle/schoo_id/ + xxx.后缀
            return COS_RESORCE_PATH+path+getUniqueFilename(file);
        }
        //模拟路径:/campus/res/sysimg/ + xxx.后缀
        return COS_RESORCE_PATH+getUniqueFilename(file);
    }


    /**
     * 设置:获取唯一文件名字
     */
    private static  String  getUniqueFilename(MultipartFile file)
    {
        String fileName = file.getOriginalFilename();
        String extension = getExtension(file);
        fileName =  IdUtils.fastUUID() + "." + extension;
        return fileName;
    }


    /**
     * 获取文件名的后缀
     *
     * @param file 表单文件
     * @return 后缀名
     */
    private static  String getExtension(MultipartFile file)
    {
        String extension = FilenameUtils.getExtension(file.getOriginalFilename());
        if (StringUtils.isEmpty(extension))
        {
            extension = MimeTypeUtils.getExtension(file.getContentType());
        }
        return extension;
    }


    /**
     *
     * 方法名称:MultipartFile 文件类型转换成File 类型
     *
     * 功能描述:
     * 〈〉
     *
     * @param multipartFile 1
     * @return : java.io.File
     * @author : Sun
     * @date : 2020/11/19
     */
    public static File transferToFile(MultipartFile multipartFile) throws Exception {
        File toFile = null;
        if (multipartFile.equals("") || multipartFile.getSize() <= 0) {
            multipartFile = null;
        } else {
            InputStream ins = null;
            ins = multipartFile.getInputStream();
            toFile = new File(multipartFile.getOriginalFilename());
            inputStreamToFile(ins, toFile);
            ins.close();
        }
        return toFile;
    }

    //获取流文件
    private static void inputStreamToFile(InputStream ins, File file) {
        try {
            OutputStream os = new FileOutputStream(file);
            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            ins.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • 封装公共上传方法工具类

代码如下(示例):

import java.io.File;

/**
 * @program: cos
 * @description: 腾讯云COS上传文件工具类
 * @author: Sun
 * @create: 2020-11-19 15:30
 **/

public class TencentCosFileUtils {

    /**
     *
     * 方法名称:腾讯COS上传文件方法
     *
     * 功能描述:
     * 〈腾讯COS上传文件方法〉
     *
     * @param multipartFile 文件名称
     * @param path 文件路径/  分类路径 将照片进行分类
     * @return : java.lang.String
     * @author : Sun
     * @date : 2020/11/19
     */
    public static String cosUploadFile(MultipartFile multipartFile, String path) {
        //1.获取存储桶客户端
        COSClient cosClient = TencentCosConfig.getCosClient();
        //2.获取对象key
        String cosFileKey = TencentCosConfig.getCosFileKey(multipartFile,path);
        try {
        //3.将multipartFile转换成FILE类型
        File localFile = TencentCosConfig.transferToFile(multipartFile);
        //4.创建存储对象的请求
        PutObjectRequest putObjectRequest = new PutObjectRequest(TencentCosConfig.COS_BUCKET_NAME, cosFileKey, localFile);
        //5.执行上传并返回结果信息
        PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);
        } catch (Exception e){
            System.out.println("-----上传文件出错-----"+e.getMessage());
            e.printStackTrace();
        }finally {
            cosClient.shutdown();
        }
        return TencentCosConfig.COS_DOMAIN_URL+cosFileKey;
    }


    /**
     * 方法名称:删除COS上的文件
     * 功能描述:
     * 〈〉
     * @param filePathUrl 1
     * @return : void
     * @author : Sun
     * @date : 2020/11/19
     */
    public static void cosDeleteFile(String filePathUrl) {
        //1.获取存储桶客户端
        COSClient cosClient = TencentCosConfig.getCosClient();
        try {
        //2.指定要删除的 对象桶 和 对象key
        String[] srr =  filePathUrl.split(TencentCosConfig.COS_DOMAIN_URL);
        String key = srr[1];
        cosClient.deleteObject(TencentCosConfig.COS_BUCKET_NAME, key);
        } catch (Exception e){
            System.out.println("-----上传文件出错-----"+e.getMessage());
            e.printStackTrace();
        }finally {
            cosClient.shutdown();
        }
    }
}

3.可能用到的工具类

  • 字符串工具类

代码如下(示例):

import java.util.Collection;
import java.util.Map;
import com.ruoyi.common.core.text.StrFormatter;

/**
 * 字符串工具类
 */
public class StringUtils extends org.apache.commons.lang3.StringUtils
{
    /** 空字符串 */
    private static final String NULLSTR = "";

    /** 下划线 */
    private static final char SEPARATOR = '_';

    /**
     * 获取参数不为空值
     * 
     * @param value defaultValue 要判断的value
     * @return value 返回值
     */
    public static <T> T nvl(T value, T defaultValue)
    {
        return value != null ? value : defaultValue;
    }

    /**
     * * 判断一个Collection是否为空, 包含List,Set,Queue
     * 
     * @param coll 要判断的Collection
     * @return true:为空 false:非空
     */
    public static boolean isEmpty(Collection<?> coll)
    {
        return isNull(coll) || coll.isEmpty();
    }

    /**
     * * 判断一个Collection是否非空,包含List,Set,Queue
     * 
     * @param coll 要判断的Collection
     * @return true:非空 false:空
     */
    public static boolean isNotEmpty(Collection<?> coll)
    {
        return !isEmpty(coll);
    }

    /**
     * * 判断一个对象数组是否为空
     * 
     * @param objects 要判断的对象数组
     ** @return true:为空 false:非空
     */
    public static boolean isEmpty(Object[] objects)
    {
        return isNull(objects) || (objects.length == 0);
    }

    /**
     * * 判断一个对象数组是否非空
     * 
     * @param objects 要判断的对象数组
     * @return true:非空 false:空
     */
    public static boolean isNotEmpty(Object[] objects)
    {
        return !isEmpty(objects);
    }

    /**
     * * 判断一个Map是否为空
     * 
     * @param map 要判断的Map
     * @return true:为空 false:非空
     */
    public static boolean isEmpty(Map<?, ?> map)
    {
        return isNull(map) || map.isEmpty();
    }

    /**
     * * 判断一个Map是否为空
     * 
     * @param map 要判断的Map
     * @return true:非空 false:空
     */
    public static boolean isNotEmpty(Map<?, ?> map)
    {
        return !isEmpty(map);
    }

    /**
     * * 判断一个字符串是否为空串
     * 
     * @param str String
     * @return true:为空 false:非空
     */
    public static boolean isEmpty(String str)
    {
        return isNull(str) || NULLSTR.equals(str.trim());
    }

    /**
     * * 判断一个字符串是否为非空串
     * 
     * @param str String
     * @return true:非空串 false:空串
     */
    public static boolean isNotEmpty(String str)
    {
        return !isEmpty(str);
    }

    /**
     * * 判断一个对象是否为空
     * 
     * @param object Object
     * @return true:为空 false:非空
     */
    public static boolean isNull(Object object)
    {
        return object == null;
    }

    /**
     * * 判断一个对象是否非空
     * 
     * @param object Object
     * @return true:非空 false:空
     */
    public static boolean isNotNull(Object object)
    {
        return !isNull(object);
    }

    /**
     * * 判断一个对象是否是数组类型(Java基本型别的数组)
     * 
     * @param object 对象
     * @return true:是数组 false:不是数组
     */
    public static boolean isArray(Object object)
    {
        return isNotNull(object) && object.getClass().isArray();
    }

    /**
     * 去空格
     */
    public static String trim(String str)
    {
        return (str == null ? "" : str.trim());
    }

    /**
     * 截取字符串
     * 
     * @param str 字符串
     * @param start 开始
     * @return 结果
     */
    public static String substring(final String str, int start)
    {
        if (str == null)
        {
            return NULLSTR;
        }

        if (start < 0)
        {
            start = str.length() + start;
        }

        if (start < 0)
        {
            start = 0;
        }
        if (start > str.length())
        {
            return NULLSTR;
        }

        return str.substring(start);
    }

    /**
     * 截取字符串
     * 
     * @param str 字符串
     * @param start 开始
     * @param end 结束
     * @return 结果
     */
    public static String substring(final String str, int start, int end)
    {
        if (str == null)
        {
            return NULLSTR;
        }

        if (end < 0)
        {
            end = str.length() + end;
        }
        if (start < 0)
        {
            start = str.length() + start;
        }

        if (end > str.length())
        {
            end = str.length();
        }

        if (start > end)
        {
            return NULLSTR;
        }

        if (start < 0)
        {
            start = 0;
        }
        if (end < 0)
        {
            end = 0;
        }

        return str.substring(start, end);
    }

    /**
     * 格式化文本, {} 表示占位符<br>
     * 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
     * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
     * 例:<br>
     * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br>
     * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
     * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
     * 
     * @param template 文本模板,被替换的部分用 {} 表示
     * @param params 参数值
     * @return 格式化后的文本
     */
    public static String format(String template, Object... params)
    {
        if (isEmpty(params) || isEmpty(template))
        {
            return template;
        }
        return StrFormatter.format(template, params);
    }

    /**
     * 下划线转驼峰命名
     */
    public static String toUnderScoreCase(String str)
    {
        if (str == null)
        {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        // 前置字符是否大写
        boolean preCharIsUpperCase = true;
        // 当前字符是否大写
        boolean curreCharIsUpperCase = true;
        // 下一字符是否大写
        boolean nexteCharIsUpperCase = true;
        for (int i = 0; i < str.length(); i++)
        {
            char c = str.charAt(i);
            if (i > 0)
            {
                preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1));
            }
            else
            {
                preCharIsUpperCase = false;
            }

            curreCharIsUpperCase = Character.isUpperCase(c);

            if (i < (str.length() - 1))
            {
                nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1));
            }

            if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase)
            {
                sb.append(SEPARATOR);
            }
            else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase)
            {
                sb.append(SEPARATOR);
            }
            sb.append(Character.toLowerCase(c));
        }
        return sb.toString();
    }

    /**
     * 是否包含字符串
     * 
     * @param str 验证字符串
     * @param strs 字符串组
     * @return 包含返回true
     */
    public static boolean inStringIgnoreCase(String str, String... strs)
    {
        if (str != null && strs != null)
        {
            for (String s : strs)
            {
                if (str.equalsIgnoreCase(trim(s)))
                {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如:HELLO_WORLD->HelloWorld
     * 
     * @param name 转换前的下划线大写方式命名的字符串
     * @return 转换后的驼峰式命名的字符串
     */
    public static String convertToCamelCase(String name)
    {
        StringBuilder result = new StringBuilder();
        // 快速检查
        if (name == null || name.isEmpty())
        {
            // 没必要转换
            return "";
        }
        else if (!name.contains("_"))
        {
            // 不含下划线,仅将首字母大写
            return name.substring(0, 1).toUpperCase() + name.substring(1);
        }
        // 用下划线将原始字符串分割
        String[] camels = name.split("_");
        for (String camel : camels)
        {
            // 跳过原始字符串中开头、结尾的下换线或双重下划线
            if (camel.isEmpty())
            {
                continue;
            }
            // 首字母大写
            result.append(camel.substring(0, 1).toUpperCase());
            result.append(camel.substring(1).toLowerCase());
        }
        return result.toString();
    }

    /**
     * 驼峰式命名法
     * 例如:user_name->userName
     */
    public static String toCamelCase(String s)
    {
        if (s == null)
        {
            return null;
        }
        if (s.indexOf(SEPARATOR) == -1)
        {
            return s;
        }
        s = s.toLowerCase();
        StringBuilder sb = new StringBuilder(s.length());
        boolean upperCase = false;
        for (int i = 0; i < s.length(); i++)
        {
            char c = s.charAt(i);

            if (c == SEPARATOR)
            {
                upperCase = true;
            }
            else if (upperCase)
            {
                sb.append(Character.toUpperCase(c));
                upperCase = false;
            }
            else
            {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    @SuppressWarnings("unchecked")
    public static <T> T cast(Object obj)
    {
        return (T) obj;
    }
}

  • 媒体类型工具类
/**
 * 媒体类型工具类
 */
public class MimeTypeUtils
{
    public static final String IMAGE_PNG = "image/png";

    public static final String IMAGE_JPG = "image/jpg";

    public static final String IMAGE_JPEG = "image/jpeg";

    public static final String IMAGE_BMP = "image/bmp";

    public static final String IMAGE_GIF = "image/gif";

    public static final String[] IMAGE_EXTENSION = { "bmp", "gif", "jpg", "jpeg", "png" };

    public static final String[] FLASH_EXTENSION = { "swf", "flv" };

    public static final String[] MEDIA_EXTENSION = { "swf", "flv", "mp3", "wav", "wma", "wmv", "mid", "avi", "mpg",
            "asf", "rm", "rmvb" };

    public static final String[] VIDEO_EXTENSION = { "mp4", "avi", "rmvb" };

    public static final String[] DEFAULT_ALLOWED_EXTENSION = {
            // 图片
            "bmp", "gif", "jpg", "jpeg", "png",
            // word excel powerpoint
            "doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt",
            // 压缩文件
            "rar", "zip", "gz", "bz2",
            // 视频格式
            "mp4", "avi", "rmvb",
            // pdf
            "pdf" };

    public static String getExtension(String prefix)
    {
        switch (prefix)
        {
            case IMAGE_PNG:
                return "png";
            case IMAGE_JPG:
                return "jpg";
            case IMAGE_JPEG:
                return "jpeg";
            case IMAGE_BMP:
                return "bmp";
            case IMAGE_GIF:
                return "gif";
            default:
                return "";
        }
    }
}

  • ID生成器工具类
/**
 * ID生成器工具类
 *
 */
public class IdUtils
{
    /**
     * 获取随机UUID
     * 
     * @return 随机UUID
     */
    public static String randomUUID()
    {
        return UUID.randomUUID().toString();
    }

    /**
     * 简化的UUID,去掉了横线
     * 
     * @return 简化的UUID,去掉了横线
     */
    public static String simpleUUID()
    {
        return UUID.randomUUID().toString(true);
    }

    /**
     * 获取随机UUID,使用性能更好的ThreadLocalRandom生成UUID
     * 
     * @return 随机UUID
     */
    public static String fastUUID()
    {
        return UUID.fastUUID().toString();
    }

    /**
     * 简化的UUID,去掉了横线,使用性能更好的ThreadLocalRandom生成UUID
     * 
     * @return 简化的UUID,去掉了横线
     */
    public static String fastSimpleUUID()
    {
        return UUID.fastUUID().toString(true);
    }
}

  • 测试接口
 @PostMapping("/testUploadFile")
    @ResponseBody
    public String testUploadFile(MultipartFile file, Integer yourUserId)
    {
        try
        {
            // 上传文件分类路径
            String filePath =yourUserId+"/";
            // 上传文件返回全路径
            String cosFilePathUrl = TencentCosFileUtils.cosUploadFile(file, filePath);
            return cosFilePathUrl;
        }
        catch (Exception e)
        {
            return e.getMessage();
        }
    }

总结

以上就是对腾讯云COS的讲解和通过COS进行文件上传的封装。谢谢大家的观看,抽空点个赞呗~

  • 8
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

颜良配情深

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值