前言
最近在练习写一个前后端分离项目,第一个完整的功能已经接近尾声,就差图片上传了,正好记录一下搭建OSS服务的过程!
什么是对象存储 OSS
摘自阿里云对象存储 OSS文档:
https://help.aliyun.com/document_detail/31817.html?spm=a2c4g.11174283.2.5.6f6d7da25wwxU3
海量、安全、低成本、高可靠的云存储服务,提供99.9999999999%的数据可靠性。使用RESTful API 可以在互联网任何位置存储和访问,容量和处理能力弹性扩展,多种存储类型供选择全面优化存储成本。
OSS 具有与平台无关的 RESTful API 接口,您可以在任何应用、任何时间、任何地点存储和访问任意类型的数据。
视频
观看以下视频,快速了解 OSS。
计费规则
https://www.aliyun.com/price/product?spm=a2c4g.11186623.2.30.578865d3hAKfyD#/oss/detail
学习的话充个几块钱即可
开通OSS
OSS管理后台
创建Buckect
- Buckect可以想象成一个数据库,一般一个项目对应一个Buckect即可
- 这里的读写权限我们一般选择公共读,让资源在任何地方都可以访问,而写操作通过我们的服务带上身份验证进行
- 其他的参数可能和价格挂钩,按需选择即可
- 创建完成后可以看到概览页面中有两个重要的地址:地域节点和Bucket域名
创建目录
- 这里创建目录是用于区分不同类型的文件
- 上传一个文件测试一下,这个URL就是我们后面要拼接的图片路径,可以用来参考
AccessKey安全
创建用户
我们要对OSS进行远程写操作,必须要创建AccessKey,阿里云提示我们用子用户创建AccessKey比较安全
- 注意:创建后记得保存AccessKeySecret,下次再进来就没了
创建用户组
用户组用于将统一的权限集合分配给多个用户
创建好用户组之后,给用户组分配权限AliyunOSSFullAccess
接着将刚刚创建的用户添加进组
总结
一系列OSS管理后台的操作都玩了一遍,到这里我们搜集到了几个信息,用于对接OSS
Bucket: hetonghao |
对接OSS SDK
参考官方Java SDK文档
https://help.aliyun.com/document_detail/84781.html?spm=5176.8466032.0.0.f6311450ACtR4P
添加pom依赖
<dependency> |
编写OSS代码
application.yml 配置
oss:
aliyun:
imagesHost: images
endPoint: oss-cn-shenzhen.aliyuncs.com
bucket: hetonghao
accessKeyId: LTAI4FgBBEeeRTMkVVFkKFEA
accessKeySecret: --------------------OssConfigProperties 用于读取配置
package cn.hetonghao.oss.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* oss配置属性
*
* @author HeTongHao
* @since 2020/4/12 14:35
*/
"oss.aliyun") (prefix =
public class OssConfigProperties {
private String imagesHost;
/**
* 地域节点
*/
private String endPoint;
private String bucket;
private String accessKeyId;
private String accessKeySecret;
}Service
package cn.hetonghao.oss.service;
import com.aliyun.oss.model.Bucket;
import org.springframework.web.multipart.MultipartFile;
/**
* oss 文件管理
*
* @author HeTongHao
* @since 2020/4/12 14:32
*/
public interface IOssFileService {
/**
* 上传文件
*
* @param multipartFile
* @return
*/
String upload(MultipartFile multipartFile);
/**
* 创建Bucket
*
* @param bucketName
* @return
*/
Bucket createBucket(String bucketName);
}Service impl
package cn.hetonghao.oss.service.impl;
import cn.hetonghao.oss.config.OssConfigProperties;
import cn.hetonghao.oss.service.IOssFileService;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.Bucket;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.CreateBucketRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Optional;
import java.util.UUID;
/**
* oss 文件管理实现
*
* @author HeTongHao
* @since 2020/4/12 14:34
*/
(OssConfigProperties.class)
public class OssFileServiceImpl implements IOssFileService {
private OssConfigProperties ossConfigProperties;
/**
* 创建OSSClient实例
*
* @return
*/
private OSS createOssClient() {
return new OSSClientBuilder().build(ossConfigProperties.getEndPoint()
, ossConfigProperties.getAccessKeyId(), ossConfigProperties.getAccessKeySecret());
}
public String upload(MultipartFile multipartFile) {
String uploadPath = null;
OSS ossClient = null;
try {
// 创建OSSClient实例。
ossClient = createOssClient();
// 对文件重命名
String oriName = Optional.ofNullable(multipartFile.getOriginalFilename()).orElse("");
// 文件按日期分类
String filePath = DateTimeFormatter.ofPattern("yyyy/MM/dd").format(LocalDate.now());
String fileName = UUID.randomUUID().toString();
String fileSuffix = oriName.substring(oriName.indexOf("."));
String fileNewName = fileName + fileSuffix;
String fileUrl = ossConfigProperties.getImagesHost() + '/' + filePath + '/' + fileNewName;
// 上传一个对象
ossClient.putObject(ossConfigProperties.getBucket(), fileUrl, multipartFile.getInputStream());
// 最后的访问路径 = Bucket+EndPoint+fileFullUrl
uploadPath = "https://" + ossConfigProperties.getBucket() + "." + ossConfigProperties.getEndPoint()
+ "/" + fileUrl;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ossClient != null) {
// 关闭OSSClient。
ossClient.shutdown();
}
}
return uploadPath;
}
public Bucket createBucket(String bucketName) {
Bucket bucket = null;
OSS ossClient = null;
try {
// 创建OSSClient实例。
ossClient = createOssClient();
CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
//设置成公共读
createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
//创建
bucket = ossClient.createBucket(createBucketRequest);
} finally {
if (ossClient != null) {
// 关闭OSSClient。
ossClient.shutdown();
}
}
return bucket;
}
}controller
/**
* 文件管理Controller
*
* @author HeTongHao
* @since 2020/4/12 15:15
*/
"文件管理") (
"file") (
public class FileController {
private IOssFileService ossFileService;
"文件上传") (
"upload") (
public SingleResponse<String> upload(@RequestBody MultipartFile file) {
return new SingleResponse<String>()
.setData(ossFileService.upload(file));
}
}
测试
上传文件
- 访问swagger页面调用api
创建Bucket
执行单元测试
(SpringRunner.class)
(classes = OssServerMain.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class OssTest {
private IOssFileService ossFileService;
public void testCreateBucket() {
System.out.println(ossFileService.createBucket("hetonghao-test-bucket"));
}
}
总结
- 至此基础的Java OSS 服务已经搭建完毕,还可以继续扩展实现,比如:删除文件、给文件进行精准的权限控制等等。
- 其它语言接入OSS如Python、Go官方都有对应的Sdk。
- 对象存储不止于OSS,其它服务商如腾讯云的COS、七牛云的KODO等都可以实现!