阿里云对象存储 阿里云官网点击
阿里云对象存储OSS(Object Storage Service)是一款海量、安全、低成本、高可靠的云存储服务,提供99.9999999999%(12个9)的数据持久性,99.995%的数据可用性。多种存储类型供选择,全面优化存储成本。【源于官网】
首先来看注册和手动申请阿里云OSS仓库
1 点击进入管理控制台
2 控制台页面
3 创建自己的Bucket
4 按照下面的方式创建Bucket
5 点击确定即可,经过以上过程,即成功申请了阿里云OSS云存储仓库
下面介绍使用Java API 操作 OSS
1 配置依赖,参考
java 8及以下,使用Maven在pom.xml中引入
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.10.2</version>
</dependency>
如果是Java9及以上或者用Eclipse开发具体可参见官方文档
2 Java API操作OSS
多种编程语言的API 点击进入
使用Java API操作OSS其实有官方文档可以借鉴,点击JavaAPI文档,在文档中,不难发现,每一个功能前面都有一系列的Access账号的认证,如下图所示
下面说说账号怎么设置
1 点击进入 OSS 控制台 进入
选择访问控制 RAM 进入,其实AccessKey也可以,但是主要影响整个仓库的安全性,所以推荐使用 箭头指向的那个
2 点击进去,创建用户
3 创建完用户后,进行权限设置
4 在搜索框中输入 oss 将四个 OSS的权限,都加进去。
如果加入成功,加入过的会变灰
使用程序进行访问OSS
1 将上面的用户信息配置到项目的 application.yml
加入下面的代码段
alioss:
endpoint: oss-cn-your location.aliyuncs.com
accessKeyId: your AccessKeyId
accessKeySecret: your AccessKeySecret
bucketName: your bucket name
其中endpoint在
2 创建OSS实体类
import org.springframework.stereotype.Component;
/*
Data:set get 方法
Component: Spring 扫描
ConfigurationProperties: 与 application.yml中的属性名保持一致
*/
@ConfigurationProperties(prefix= "alioss")
@Component
@Data
public class OssEntity {
private String endpoint;
private String accessKeyId;
private String accessKeySecret;
private String bucketName;
}
3 创建Service 接口
import java.io.IOException;
public interface AliOssService {
/**
* 创建存储空间
*/
void createBucket();
/**
* 上传文件
* @param file 文件对象
* @return
*/
String upload(MultipartFile file);
/**
* 下载文件
* @throws IOException
*/
void download(String fileName) throws IOException;
/**
* 列举文件
*/
void listFile();
/**
* 删除文件
*/
void deleteFile(String fileName);
}
4 ServiceImpl类
可借鉴OSS Java API 开发文档
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.*;
import com.s.system.entity.OssEntity;
import com.s.system.service.AliOssService;
import net.sf.jsqlparser.expression.DateTimeLiteralExpression;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Date;
import java.util.UUID;
//在创建AliOssServiceImpl类的时候将属性值封装
@Service
public class AliOssServiceImpl implements AliOssService, InitializingBean {
@Autowired
private OssEntity ossEntity;
//存放endpoint地址
private String endpoint;
private String accessKeyId;
private String accessKeySecret;
private String bucketName;
@Override
public void createBucket() {
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
if (ossClient.doesBucketExist(bucketName)) {
throw new RuntimeException(bucketName + "在对象存储的Bucket列表中已经存在");
}
// 创建存储空间。
ossClient.createBucket(bucketName);
// 关闭OSSClient。
ossClient.shutdown();
}
@Override
public String upload(MultipartFile file) {
//上传地址
String uploadUrl = null;
try {
//判断oss实例是否存在:如果不存在则创建,如果存在则获取
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
if (!ossClient.doesBucketExist(bucketName)) {
//创建bucket
ossClient.createBucket(bucketName);
//设置oss实例的访问权限:公共读
ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
}
//获取上传文件流
InputStream inputStream = file.getInputStream();
//构建日期路径:avatar/2020/07/31/文件名
String datePath = new DateTimeLiteralExpression.DateTime().toString("yyyy/MM/dd");
//文件名:uuid.扩展名
//获取上传文件的全名称
String original = file.getOriginalFilename();
//去掉uuid中生成的-
String fileName = UUID.randomUUID().toString().replaceAll("-", "");
//截取掉文件获得扩展名
String fileType = original.substring(original.lastIndexOf("."));
//uuid+.jpg/.png
String newName = fileName + fileType;
// yyyy/MM/dd+/uuid+.jpg/.png
fileName = datePath + "/" + newName;
//如果想要实现图片的预览效果,一定要设置一下几个点
//1.设置文件 ACL为反正不能为私有 要么是公共读,要么是公共读写
//2.一定要设置文本类型为(image/jpg)
ObjectMetadata objectMetadata = new ObjectMetadata();
//设置公共读权限
objectMetadata.setObjectAcl(CannedAccessControlList.PublicRead);
//设置类型
objectMetadata.setContentType(getcontentType(fileName.substring(fileName.lastIndexOf("."))));
//文件上传至阿里云
ossClient.putObject(bucketName, fileName, inputStream, objectMetadata);
// 关闭OSSClient。
ossClient.shutdown();
//默认十年不过期
Date expiration = new Date(System.currentTimeMillis() + 3600L * 1000 * 24 * 365 * 10);
//bucket名称 文件名 过期时间
uploadUrl = ossClient.generatePresignedUrl(bucketName, fileName, expiration).toString();
//获取url地址
//uploadUrl = "https://" + bucketName + "." + endPoint + "/" + fileName;
} catch (IOException e) {
e.printStackTrace();
}
return uploadUrl.substring(0, uploadUrl.indexOf("?"));
//return uploadUrl;
}
@Override
public void download(String fileName) throws IOException {
// <yourObjectName>从OSS下载文件时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg。
String objectName = fileName;
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
// 调用ossClient.getObject返回一个OSSObject实例,该实例包含文件内容及文件元信息。
OSSObject ossObject = ossClient.getObject(bucketName, objectName);
// 调用ossObject.getObjectContent获取文件输入流,可读取此输入流获取其内容。
InputStream content = ossObject.getObjectContent();
if (content != null) {
BufferedReader reader = new BufferedReader(new InputStreamReader(content));
while (true) {
String line = reader.readLine();
if (line == null) {
break;
}
System.out.println("\n" + line);
}
// 数据读取完成后,获取的流必须关闭,否则会造成连接泄漏,导致请求无连接可用,程序无法正常工作。
content.close();
}
// 关闭OSSClient。
ossClient.shutdown();
}
@Override
public void listFile() {
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
// ossClient.listObjects返回ObjectListing实例,包含此次listObject请求的返回结果。
ObjectListing objectListing = ossClient.listObjects(bucketName);
// objectListing.getObjectSummaries获取所有文件的描述信息。
for (OSSObjectSummary objectSummary : objectListing.getObjectSummaries()) {
System.out.println(" - " + objectSummary.getKey() + " " +
"(size = " + objectSummary.getSize() + ")");
}
// 关闭OSSClient。
ossClient.shutdown();
}
@Override
public void deleteFile(String fileName) {
// <yourObjectName>从OSS下载文件时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg。
String objectName = fileName;
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
// 删除文件。
ossClient.deleteObject(bucketName, objectName);
// 关闭OSSClient。
ossClient.shutdown();
}
//初始化Bean之后需要进行的操作
@Override
public void afterPropertiesSet() throws Exception {
Endpoint以杭州为例,其它Region请按实际情况填写。
endpoint = ossEntity.getEndpoint();
阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录RAM控制台创建RAM账号。
accessKeyId = ossEntity.getAccessKeyId();
accessKeySecret = ossEntity.getAccessKeySecret();
bucketName = ossEntity.getBucketName();
}
/**
* Description: 判断OSS服务文件上传时文件的contentType
*
* @param FilenameExtension 文件后缀
* @return String
*/
public static String getcontentType(String FilenameExtension) {
if (FilenameExtension.equalsIgnoreCase(".bmp")) {
return "image/bmp";
}
if (FilenameExtension.equalsIgnoreCase(".gif")) {
return "image/gif";
}
if (FilenameExtension.equalsIgnoreCase(".jpeg") ||
FilenameExtension.equalsIgnoreCase(".jpg") ||
FilenameExtension.equalsIgnoreCase(".png")) {
return "image/jpg";
}
if (FilenameExtension.equalsIgnoreCase(".html")) {
return "text/html";
}
if (FilenameExtension.equalsIgnoreCase(".txt")) {
return "text/plain";
}
if (FilenameExtension.equalsIgnoreCase(".vsd")) {
return "application/vnd.visio";
}
if (FilenameExtension.equalsIgnoreCase(".pptx") ||
FilenameExtension.equalsIgnoreCase(".ppt")) {
return "application/vnd.ms-powerpoint";
}
if (FilenameExtension.equalsIgnoreCase(".docx") ||
FilenameExtension.equalsIgnoreCase(".doc")) {
return "application/msword";
}
if (FilenameExtension.equalsIgnoreCase(".xml")) {
return "text/xml";
}
return "image/jpg";
}
}
5 测试
import com.s.system.entity.OssEntity;
import com.s.system.service.AliOssService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class OssTest {
@Autowired
private OssEntity ossEntity;
@Autowired
private AliOssService aliOssService;
@Test
public void contextLoads(){
aliOssService.createBucket();
System.out.println(ossEntity.toString());
}
}
测试通过后,可以发现,这个错误主要是在 aplication.yml 中已经存在了 该 bucket,可以自行再将 application.yml 中的 bucketName: your bucket name 定义一个新的名字,就可以通过了。这也就说明OSS Demo 测试通过,可以进行下面的开发了。