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进行模糊查询等一些列操作, 基本能满足项目需要
模糊查询
有疑问的小伙伴可以留言我们一起探讨哈