Java访问QingCloud青云对象存储

网上关于小白如何访问青云的相关的博客真是少之又少啊, 正好我们项目中用到了就给大家整理下哈

首先:
如果大家想了解访问青云的操作, 先确定一下我们要访问的是公有云还是私有云
(自己买来玩的或者用来写demo练习的话, 公有云就够了, 怎么操作可以去青云的官网查看帮助文档和API 一般企业使用的话大部分都是用的私有云)
官网上的API不适用于私有云! 私有云和公有云访问可能有一丢丢的差别

其次:
本篇文章介绍的是访问的本人公司的私有云,
(如果不了解青云的一些基本参数的同学, 建议您也先去青云官网熟悉一下)

言归正传:
前段时间, 项目中要存储音频文件在云服务器上, 我们公司选择了使用青云的对象存储
(个人感觉和es搜索引擎、mongoDB类似,都是key value形式的, 也都有元数据啥的, 代码层面和redis差不多, 也就是工具类不一样而已, 没接触过的童鞋不用把他想的有多难)

  • 先引入依赖↓
<dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-s3</artifactId>
            <version>1.11.433</version>
        </dependency>

这个s3请教了大佬, 大概可以理解为这个就是个亚马逊的一个约定, 凡是符合亚马逊这个约定的云存储, 都能用这个依赖和用下方工具类访问

(大佬说目前云存储大部分都遵守这个约定)

(大家也可以百度一下, 我理解的不一定准确)

青云容器部署_青云容器部署

  • 接下来是工具类代码↓ (直接粘贴就能用)

(不过我这多引用了一个阿里云的依赖进行判空,不需要的小伙伴可以把判空代码删掉)

package com.ruoyi.voice.utils;

import com.aliyun.oss.common.utils.StringUtils;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.Protocol;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.*;
import com.amazonaws.services.s3.model.DeleteObjectsRequest.KeyVersion;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 对象存储工具类,用于操作附件 
 */
@Data
public class HS3Util {

    private ClientConfiguration myClientConfig = new ClientConfiguration();

    private AmazonS3 hs3Client = null;
	// 私有云地址 
    private String endpointName = "s3.xxxx.stor.xxxxx.com";
    // 地区编码 
    private String signingRegion = "pek3b";
    // 这个是桶名称   (可以浅理解为mysql的库)
    private String bucketName = "xxxxxxx";
    // 这个就是你访问云服务器的账号一样 (运维同事应该会告你)
    private String accessKey = "API密钥ID";
    // 这个就相当于密码(运维给你)
    private String secretKey = "私钥";


    private Map<String, AmazonS3> pool = new HashMap();
    public HS3Util(){}

    public HS3Util(String endpointName, String signingRegion, String bucketName, String accessKey, String secretKey) {
        if (!StringUtils.isNullOrEmpty(endpointName)) {
            this.endpointName = endpointName;
        }
        if (!StringUtils.isNullOrEmpty(signingRegion)) {
            this.signingRegion = signingRegion;
        }
        if (!StringUtils.isNullOrEmpty(bucketName)) {
            this.bucketName = bucketName;
        }
        this.accessKey = accessKey;
        this.secretKey = secretKey;
        hs3Clientbuild(this.accessKey, this.secretKey);
    }

    public HS3Util(String accessKey, String secretKey) {
        this.accessKey = accessKey;
        this.secretKey = secretKey;
        hs3Clientbuild(this.accessKey, this.secretKey);
    }


    private void hs3Clientbuild(String accessKey, String secretKey) {
        AwsClientBuilder.EndpointConfiguration endpointConfiguration = new AwsClientBuilder.EndpointConfiguration(endpointName, signingRegion);
        AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
        ClientConfiguration conf = new ClientConfiguration();
        conf.setProtocol(Protocol.HTTP);
        hs3Client = AmazonS3ClientBuilder.standard()
                .withCredentials(new AWSStaticCredentialsProvider(credentials))
                .withEndpointConfiguration(endpointConfiguration)
                .withClientConfiguration(conf)
                .build();
    }

    /**
     * 附件上传
     *
     * @param objectKey   附件key
     * @param inputStream 附件流
     * @throws Exception
     */
    public void upload(String catalog, String objectKey, InputStream inputStream) throws Exception {
        if (null == inputStream) {
            return;
        }
        createDir(bucketName, catalog);
        createObject(objectKey, inputStream);
    }

    /**
     * 附件上传
     *
     * @param objectKey   附件key
     * @param inputStream 附件流
     * @throws Exception
     */
    public void uploadOld(String objectKey, InputStream inputStream) throws Exception {
        if (null == inputStream) {
            return;
        }
        createObject(objectKey, inputStream);
    }

    /***
     * @author: panchunming-ghq
     * @description: 一次性上传多个文件(一个或一个以上的文件上传,只上传文件,不考虑重名,不会每次上传就将文件名称、路径等信息记录到数据库中
     *               只上传,不做任何记录)
     * @param: catalog  * @param: hs3Properties  * @param: multipartFiles
     * @return: java.lang.Boolean
     * @date: 2020/10/26
     */
    public Boolean uploadFile(String catalog, String bucketName, MultipartFile[] multipartFiles) throws Exception {
        Boolean result = false;
        createDir(bucketName, catalog);
        // 上传文件到这个目录下
        for (MultipartFile multipartFile : multipartFiles) {
            String objectKey = catalog + multipartFile.getOriginalFilename();
            InputStream inputStream = multipartFile.getInputStream();
            createObject(objectKey, inputStream);
        }
        return result;
    }

    /**
     * * 附件上传并检查是否成功
     *
     * @param catalog     目录路径(必须以"/"结尾)
     * @param objectKey   文件路径(以文件名结尾)
     * @param inputStream 文件输入流
     * @return
     * @throws Exception
     */
    public boolean uploadFile(String catalog, String objectKey, InputStream inputStream) throws Exception {
        if (null == catalog) {
            new Exception("文件目录路径异常!");
        } else if (null == objectKey) {
            new Exception("文件路径异常!");
        } else if (null == inputStream) {
            new Exception("文件流异常!");
        }
        createDir(bucketName, catalog);
        createObject(objectKey, inputStream);
        return checkAtt(objectKey);
    }

    /**
     * 附件下载
     *
     * @param objectKey 附件key
     * @return 附件流
     * @throws Exception
     */
    public S3ObjectInputStream downLoad(String objectKey) throws Exception {
        if (!StringUtils.isNullOrEmpty(objectKey)) {
            return getObject(objectKey);
        } else {
            return null;
        }
    }

    /**
     * 删除附件
     *
     * @param objectKey 附件key
     * @throws Exception
     */
    public void delete(String objectKey) throws Exception {
        if (!StringUtils.isNullOrEmpty(objectKey)) {
            deleteObject(objectKey);
        }
    }

    /**
     * 根据文件流创建对象 panchunming-ghq
     *
     * @param objectKey 对象的key;fileInputStream 文件流
     * @return void
     * @throws Exception
     */
    public void createObject(String objectKey, InputStream inputStream) throws Exception {
        PutObjectRequest req = new PutObjectRequest(bucketName, objectKey, inputStream, null);
        hs3Client.putObject(req);
    }

    /**
     * 获取对象文件流
     *
     * @param objectKey
     * @return 对象文件流
     * @throws Exception
     */
    private S3ObjectInputStream getObject(String objectKey) throws Exception {
        GetObjectRequest req = new GetObjectRequest(bucketName, objectKey);
        S3Object obj = hs3Client.getObject(req);
        S3ObjectInputStream s3i = obj.getObjectContent();
        return s3i;
    }

    /**
     * 获取对象文件流
     *
     * @param objectKey
     * @return 对象文件流
     * @throws Exception
     */
    public S3Object getS3Object(String objectKey) throws Exception {
        GetObjectRequest req = new GetObjectRequest(bucketName, objectKey);
        S3Object obj = hs3Client.getObject(req);
        return obj;
    }

    /**
     * 检验附件是否存在
     *
     * @param objectKey 附件key
     * @return 是否存在
     */
    public boolean checkAtt(String objectKey) {
        boolean flag = checkObject(objectKey);
        return flag;
    }

    // 检查目录
    public boolean checkObject(String objectKey) {
        boolean flag = hs3Client.doesObjectExist(bucketName, objectKey);
        return flag;
    }

    /**
     * 创建目录,先检查目录是否存在,如果不存在则创建目录
     *
     * @param bucketName 桶名
     * @param objectKey  目录
     */
    public void
    createDir(String bucketName, String objectKey) {
        boolean flag = checkObject(objectKey);
        if (!flag) {
            PutObjectRequest req = new PutObjectRequest(bucketName, objectKey, new ByteArrayInputStream(new byte[0]),
                    null);
            hs3Client.putObject(req);
        }
    }

    /**
     * 删除对象
     *
     * @param objectKey 附件key
     * @throws Exception
     */
    public void deleteObject(String objectKey) throws Exception {
        DeleteObjectRequest req = new DeleteObjectRequest(bucketName, objectKey);
        hs3Client.deleteObject(req);
    }


    public ListObjectsV2Result getListObjectsV2Request(Integer maxKey, String marker, String delimiter, String prefix) {
        ListObjectsV2Request listObjectsV2Request = new ListObjectsV2Request().
                withBucketName(bucketName).withMaxKeys(maxKey);
        if (!StringUtils.isNullOrEmpty(marker)) {
            listObjectsV2Request.withContinuationToken(marker);
        }
        if (!StringUtils.isNullOrEmpty(delimiter)) {
            listObjectsV2Request.withDelimiter(delimiter);
        }
        if (!StringUtils.isNullOrEmpty(prefix)) {
            listObjectsV2Request.withPrefix(prefix);
        }
        ListObjectsV2Result listObjectsV2Result = hs3Client.listObjectsV2(listObjectsV2Request);
        return listObjectsV2Result;
    }

    public ObjectListing getListObjectsV1Request(Integer maxKey, String prefix) {
        ObjectListing listObjectsV1Request = this.getListObjectsV1Request(maxKey, null, null, null);
        return listObjectsV1Request;
    }

    public ObjectListing getListObjectsV1Request(Integer maxKey, String marker, String delimiter, String prefix) {
        ListObjectsRequest listObjectsRequest = new ListObjectsRequest().withBucketName(bucketName).withMaxKeys(maxKey);
        if (!StringUtils.isNullOrEmpty(marker)) {
            listObjectsRequest.withMarker(marker);
        }
        if (!StringUtils.isNullOrEmpty(delimiter)) {
            listObjectsRequest.withDelimiter(delimiter);
        }
        if (!StringUtils.isNullOrEmpty(prefix)) {
            listObjectsRequest.withPrefix(prefix);
        }
        ObjectListing objectListing = hs3Client.listObjects(listObjectsRequest);
        return objectListing;
    }

    /**
     * 获取所有的Bucket
     *
     * @return
     */
    public List<Bucket> getBucketList() {
        List<Bucket> buckets = hs3Client.listBuckets();
        return buckets;
    }

    /**
     * 删除Bucket
     *
     * @param bucketName
     * @throws Exception
     */
    public void deleteBucket(String bucketName) throws Exception {
        hs3Client.deleteBucket(bucketName);
    }

    public void deleteObjects(List<String> keys) {
        DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest(bucketName);

        if (!CollectionUtils.isEmpty(keys)) {
            List<KeyVersion> list = new ArrayList<>();
            for (String key : keys) {
                KeyVersion keyVersion = new KeyVersion(key);
                list.add(keyVersion);
            }
            deleteObjectsRequest.withKeys(list);
        }
        hs3Client.deleteObjects(deleteObjectsRequest);

    }

    /**
     * 获取对象的权限
     *
     * @return
     */
    public AccessControlList getObjectACL(String objectKey) {
        GetObjectAclRequest getObjectAclRequest = new GetObjectAclRequest(bucketName, objectKey);
        AccessControlList objectAcl = hs3Client.getObjectAcl(getObjectAclRequest);
        return objectAcl;
    }

    /**
     * 获取对象的权限
     *
     * @return
     */
    public AccessControlList getBucketAcl() {
        AccessControlList bucketAcl = hs3Client.getBucketAcl(bucketName);
        return bucketAcl;
    }

    /**
     * 获取对象的权限
     *
     * @return
     */
    public AccessControlList getBucketAcl(String bucketName) {
        AccessControlList bucketAcl = hs3Client.getBucketAcl(bucketName);
        return bucketAcl;
    }


    public String getBucketLocation() {
        String bucketLocation = hs3Client.getBucketLocation(bucketName);
        return bucketLocation;
    }
}

这个工具类有的地方可能有一些小瑕疵, 使用的时候可以注意一下, 酌情修改

自己写个接口测试测试, 还能根据key进行模糊查询等一些列操作, 基本能满足项目需要

青云容器部署_1024程序员节_02


模糊查询

青云容器部署_aws_03

有疑问的小伙伴可以留言我们一起探讨哈