美文网首页个人学习
JAVA进阶篇(9)—实现网络照片的上传和下载(腾讯云cos)

JAVA进阶篇(9)—实现网络照片的上传和下载(腾讯云cos)

作者: 小胖学编程 | 来源:发表于2020-09-14 18:19 被阅读0次

对象存储服务(Cloud Object Service)是面向企业和个人开发者提供的高可用,高稳定,强安全的云端存储服务。您可以将任意数量和形式的非结构化数据放入COS,并在其中实现数据的管理和处理。COS支持标准的Restful API接口,您可以快速上手使用,按实际使用量计费,无最低使用限制。

1. 代码接入

1.1 引入依赖

引入腾讯云cos的依赖jar包。

<dependency>
    <groupId>com.qcloud</groupId>
    <artifactId>cos_api</artifactId>
    <version>5.6.8</version>
</dependency>
<dependency>
     <groupId>com.tencent.cloud</groupId>
     <artifactId>cos-sts-java</artifactId>
     <version>3.0.5</version>
</dependency>

1.2 网络图片的下载

网络图片的下载,是将照片读取为base64的格式。注意,读取下来需要加上data:image/png;base64,的前缀(此前缀为png格式)。

在实际的照片下载中,可以根据文件的后缀类型,转换成对应类型的base64格式的照片信息。

@Slf4j
public class ImgUtil {

    /**
     * 根据照片的后缀类型转换照片
     *
     * @param netImagePath 网络图片地址,格式必须以xxx.xxx(xxx.png)
     * @return 照片的base64
     */
    public static String NetImageToBase64ByImgSuffix(String netImagePath) {
        String[] split = netImagePath.split("\\.");
        String s = split[split.length - 1];
        //格式
        String prefix = String.format("data:image/%s;base64,", s);
        return NetImageToBase64(netImagePath, prefix);
    }


    /**
     * 将网络照片转换为base64格式的照片
     *
     * @param netImagePath 原照片地址
     * @param prefix       base64的照片的类型,格式data:image/png;base64,
     * @return base64格式的照片,
     */
    public static String NetImageToBase64(String netImagePath, String prefix) {
        ByteArrayOutputStream data = new ByteArrayOutputStream();
        String strNetImageToBase64;
        try {
            // 创建URL
            URL url = new URL(netImagePath);
            final byte[] by = new byte[1024];
            // 创建链接
            final HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(5000);
            InputStream is = conn.getInputStream();
            // 将内容读取内存中
            int len;
            while ((len = is.read(by)) != -1) {
                data.write(by, 0, len);
            }
            // 对字节数组Base64编码
            BASE64Encoder encoder = new BASE64Encoder();
            strNetImageToBase64 = prefix + encoder.encode(data.toByteArray());
        } catch (IOException e) {
            log.error("下载失败", e);
            throw new RuntimeException(e);
        }
        return strNetImageToBase64;
    }
}

1.3 文件的上传

  1. 根据base64的前缀决定上传照片的类型;
  2. 使用腾讯云cos的提供的类实现文件的上传;
  3. url文件目录路径就是存储在cos的文件目录路径;
@Slf4j
public class ImgUtil {

    /**
     * 保存照片
     * data:image/jpg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD
     *
     * @param base64Str  base64的照片流
     * @param secretId   腾讯云的SecretId(永久的,可在控制台开启或关闭)
     * @param secretKey  腾讯云的SecretKey(永久的,可在控制台开启或关闭)
     * @param region     腾讯云的region(bucket所在地区)
     * @param bucketName 存储桶的名称
     * @return 图片地址
     */
    public static String saveFile(String base64Str, String secretId, String secretKey, String region, String bucketName) {
        String[] d = base64Str.split("base64,");
        String dataPrefix;
        String data;
        if (d.length == 2) {
            dataPrefix = d[0];  //data:image/jpg;格式
            data = d[1]; ///9j/4AAQSkZJRgABAQAAAQABAAD...格式
        } else {
            log.error("上传失败,数据不合法,base64Str:" + base64Str);
            throw new RuntimeException("上传失败,数据不合法");
        }
        String fileName = getFileName(dataPrefix);
        byte[] fileOut = base64ToBytes(data);
        CosClientFactory instance = CosClientFactory.getInstance(secretId, secretKey, region);
        //生成文件名(pro/xxx/www/2020/9/12/UUID.png)
        String fileKey = "pro" + "/xxx" + "/www/" + calculatePath() + fileName;
        //上传到腾讯云
        instance.uploadFile(bucketName, fileKey, fileOut);
        return fileKey;
    }

    /**
     * 转换为base64的字节数组
     *
     * @param base64Str base64的字符串
     * @return 字节数组
     */
    public static byte[] base64ToBytes(String base64Str) {
        Assert.notNull(base64Str, "base64Str empty");
        return Base64.decodeBase64(base64Str);
    }

    /**
     * 文件的路径,时间单位
     *
     * @return 目录名
     */
    public static String calculatePath() {
        Calendar calendar = Calendar.getInstance();
        String year = String.valueOf(calendar.get(Calendar.YEAR));
        String month = String.valueOf(calendar.get(Calendar.MONTH) + 1);
        String date = String.valueOf(calendar.get(Calendar.DATE));
        //目录名
        return year + "/" + month + "/" + date + "/";
    }

    /**
     * 获取文件名:UUID+.后缀
     *
     * @param dataPrix base64的前缀
     * @return 后缀
     */
    public static String getFileName(String dataPrix) {
        String suffix;
        if ("data:image/jpg;".equalsIgnoreCase(dataPrix)) {
            suffix = ".jpg";
        } else if ("data:image/jpeg;".equalsIgnoreCase(dataPrix)) {
            suffix = ".jpg";
        } else if ("data:image/x-icon;".equalsIgnoreCase(dataPrix)) {
            suffix = ".ico";
        } else if ("data:image/gif;".equalsIgnoreCase(dataPrix)) {
            suffix = ".gif";
        } else if ("data:image/png;".equalsIgnoreCase(dataPrix)) {
            suffix = ".png";
        } else {
            throw new RuntimeException("上传图片格式不合法");
        }
        return UUID.randomUUID() + suffix;
    }
}

文件上传类的相关代码:

@Slf4j
public class CosClientFactory {
    private static volatile CosClientFactory cosClientFactory;

    //腾讯云的SecretId(永久的,可在控制台开启或关闭)
    private String secretId;

    //腾讯云的SecretKey(永久的,可在控制台开启或关闭)
    private String secretKey;

    //腾讯云的region(bucket所在地区)
    private String region;

    //cos的客户端
    private COSClient cos;

    private CosClientFactory(String secretId, String secretKey, String region) {
        this.secretId = secretId;
        this.secretKey = secretKey;
        this.region = region;
    }

    /**
     * 单例模式,创建唯一对象。
     * 双锁机制。
     *
     * @param secretId  腾讯云的SecretId
     * @param secretKey 腾讯云的SecretKey
     * @param region    腾讯云的region
     * @return cos的客户端
     */
    public static CosClientFactory getInstance(String secretId, String secretKey, String region) {
        if (cosClientFactory == null) {
            synchronized (CosClientFactory.class) {
                if (cosClientFactory == null) {
                    cosClientFactory = new CosClientFactory(secretId, secretKey, region);
                }
            }
            //初始化用户信息
        }
        return cosClientFactory;
    }

    /**
     * 上传照片
     */
    public void uploadFile(String bucketName, String fileName, byte[] fileBytes) {
        COSClient cosClient = getCosClient();
        uploadFile2Tx(cosClient, bucketName, fileName, fileBytes);
    }

    /**
     * 向腾讯云上传文件
     *
     * @param fileBytes  文件的字节数组
     * @param cosClient  cos客户端
     * @param bucketName 存储桶的名字
     * @param fileName   文件的名字
     * @throws IOException
     */
    public void uploadFile2Tx(COSClient cosClient, String bucketName, String fileName, byte[] fileBytes) {
        ByteArrayInputStream input = null;
        try {
            input = new ByteArrayInputStream(fileBytes);
            ObjectMetadata objectMetadata = new ObjectMetadata();
            // 设置输入流长度
            objectMetadata.setContentLength(input.available());
            // 上传文件。<yourLocalFile>由本地文件路径加文件名包括后缀组成,例如/users/local/myfile.txt。
            PutObjectResult putObjectResult = cosClient.putObject(bucketName, fileName, input, objectMetadata);
        } catch (CosServiceException serviceExp) {
            log.error("上传文件失败", serviceExp);
            throw serviceExp;
        } catch (CosClientException e) {
            log.error("上传文件失败", e);
        } finally {
            //关闭网络连接
            if (cosClient != null) {
                cosClient.shutdown();
            }
        }
    }

    //调用完毕,需要关闭网络连接
    private COSClient getCosClient() {
        if (null == cos) {
            // 1 初始化用户身份信息(secretId, secretKey)。
            COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
            // 2 设置 bucket 区域。
            ClientConfig clientConfig = new ClientConfig(new Region(region));
            // 3 生成 cos 客户端。
            cos = new COSClient(cred, clientConfig);
        }
        return cos;
    }
}

1.4 相关的配置

可以配置在配置文件中进行访问。

# 这些配置在腾讯云控制台都可查到(使用时替换为你自己的)
# 腾讯云的SecretId(永久的,可在控制台开启或关闭)
tencent.SecretId=Dug3RhGtKp8Df4FgAKt7H1ivGH7kfDiJ6UEo
# 腾讯云的SecretKey(永久的,可在控制台开启或关闭)
tencent.SecretKey=cGUanub0FYl9pQmpkU3YpyRpB93NdBXf
# 腾讯云的bucket (存储桶)
tencent.bucket=dintalk-1228321366
# 腾讯云的region(bucket所在地区)
tencent.region=ap-beijing
# 腾讯云的访问基础链接:
tencent.baseUrl= https:/dintalk-1228321366.cos.ap-beijing.myqcloud.com/

推荐阅读

腾讯云COS对象存储的简单使用

相关文章

网友评论

    本文标题:JAVA进阶篇(9)—实现网络照片的上传和下载(腾讯云cos)

    本文链接:https://www.haomeiwen.com/subject/cpwaektx.html