在项目中,我们通常需要存储一些非结构化的数据,比如:图片文件,视频文件,音频文件等数据,为了方便的存储这些数据,我们会使用对象存储服务,以用阿里云的对象存储服务为例
对象存储基本概念:
- 对象: 在MinIO中对象指的是二进制数据,甚至有时指的是Blob(Binary Large OBject),二进制数据可以是图片,音视频文件,可执行文件等等
- 桶(bucket): MinIO用桶来组织对象,一个桶类似于操作系统中的一个目录,一个桶中可以存储任意多个对象
开通对象存储服务
首先进入阿里云官网——产品

进入oss页面点击立即开通


点击立即去支付即可

开通免费使用
点击立即使用,开通免费试用


创建bucket



开启公共访问
创建好桶之后,默认桶中的数据不允许直接通过url访问,所以我们需要打开公共访问权限



创建RAM账号
这里说明一下,为了安全起见,我们创建一个RAM子账号,给子账号授权管理OSS权限,通过子账号的ACCESS KEY来访问OSS。我们的最终目的是获取RAM账号的AceessKeyId和AccessKey Secret



最终在这里获取到AccessKeyId和AccessKey Secret

给RAM账号授权OSS操作权限



引入依赖
<!-- https://mvnrepository.com/artifact/com.aliyun.oss/aliyun-sdk-oss -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.15.2</version>
</dependency>
使用demo
这里阿里云产品文档中Java代码实现的demo
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import java.io.ByteArrayInputStream;
public class OssDemo {
public static void main(String[] args) throws Exception {
// Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
String accessKeyId = "yourAccessKeyId";
String accessKeySecret = "yourAccessKeySecret";
// 填写Bucket名称,例如examplebucket。
String bucketName = "examplebucket";
// 填写Object完整路径,例如exampledir/exampleobject.txt。Object完整路径中不能包含Bucket名称。
String objectName = "exampledir/exampleobject.txt";
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
try {
String content = "Hello OSS";
ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content.getBytes()));
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}
在创建Bucket的时候,我们指定了bucket名称,选择了服务器所在地域(所在地域决定了endpoint)
其中有这样的几项信息
# 武汉地域对应的endpoint
endpoint=oss-cn-wuhan-lr.aliyuncs.com
bucket=你自己定义的名称
# 另外要访问OSS还需要AccessKey和AccessSecret,这个请保管好,不要泄露出去
accessKey=你自己的accessKey
accessSecret=你自己的accessSecret
接着我们利用这些值,上传一下本地文件
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.PutObjectResult;
import java.io.File;
import java.io.FileInputStream;
import java.util.UUID;
public class Demo {
public static void main(String[] args) throws Exception {
// Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
String endpoint = "oss-cn-beijing.aliyuncs.com";
// 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
String accessKeyId = "LTAI5tPomn5sTKq2kgBxFDz1";
String accessKeySecret = "RPQtyACBzSRmcAVZ58K3hWh1Q5l5mY";
// 填写Bucket名称,例如examplebucket。
String bucketName = "cskaoyan-word";
String path = "d:/tmp";
String fileName = "ikun.jpeg";
// 填写Object完整路径,例如exampledir/exampleobject.txt。Object完整路径中不能包含Bucket名称。
String suffix = fileName.substring(fileName.lastIndexOf("."));//ikun.jpeg suffix=.jpeg
String objectName = UUID.randomUUID().toString() + suffix;
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(new File(path, fileName));
// 保存在哪个bucket、保存的文件名、输入流
PutObjectResult putObjectResult = ossClient.putObject(bucketName, objectName, inputStream);
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
if (inputStream != null) {
inputStream.close();
}
}
}
}
那么我们后面方便使用可以封装为方法
封装
上传file,我们使用SpringMVC的Handler接收为MultipartFile,然后获得inputStream来完成上传,该方法的返回值为上传结果访问的URL,除了可以向OSS的桶中存放文件完成文件上传外,我们还可以删除OSS的桶中的文件
@Service
@Slf4j
public class OssServiceImpl implements OssService{
/**
* 文件上传
*/
@Override
public String upload(MultipartFile file) throws IOException {
String endpoint = "oss-cn-beijing.aliyuncs.com";
String accessKeyId = "LTAI5t8gpxPTCR6W58RnZq4u";
String accessKeySecret = "mVPbpbxia0JQotb7HyJAREV8QUuq8h";
String bucketName = "wdproject2";
// 构造桶中的对象名称
String originalFilename = file.getOriginalFilename();
String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
String objectName = UUID.randomUUID() + extension;
String region = "beijing";
// 创建 OSSClient 实例
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
try {
// 向桶中放入指定名称的对象
ossClient.putObject(aliOssProperties.getBucketName(), objectName, file.getInputStream());
//文件访问路径规则 https://BucketName.Endpoint/ObjectName
StringBuilder stringBuilder = new StringBuilder("https://");
stringBuilder.append(aliOssProperties.getBucketName())
.append(".")
.append(aliOssProperties.getEndpoint())
.append("/")
.append(objectName);
} catch (OSSException oe) {
log.error("阿里OSS异常,Error Message:{}", oe.getErrorMessage());
} catch (ClientException ce) {
log.error("阿里OSS Client异常,Error Message:{}", ce.getMessage());
} finally {
if (!ObjectUtils.isEmpty(ossClient)) {
ossClient.shutdown();
}
}
// 返回访问文件的url
return stringBuilder.toString();
}
@Override
public void deleteFile(String objectName) {
String endpoint = "oss-cn-beijing.aliyuncs.com";
String accessKeyId = "LTAI5t8gpxPTCR6W58RnZq4u";
String accessKeySecret = "mVPbpbxia0JQotb7HyJAREV8QUuq8h";
String bucketName = "wdproject2";
String region = "beijing";
// 创建 OSSClient 实例
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
try {
// 删除桶中指定对象
ossClient.deleteObject(bucketName, objectName);
} catch (OSSException oe) {
log.error("阿里OSS异常,Error Message:{}", oe.getErrorMessage());
} catch (ClientException ce) {
log.error("阿里OSS Client异常,Error Message:{}", ce.getMessage());
} finally {
if (!ObjectUtils.isEmpty(ossClient)) {
ossClient.shutdown();
}
}
}
}