阿里云对象存储服务-OSS
目前在一些网站中,其中的图片都放置在一个统一的图床中,用专门一个服务器来做图床,从而减轻主服务器的压力,而且相比于一般的服务器来说,图床服务器价格低廉,容量大。我们把这些图床服务器叫做对象存储服务。
对象存储服务是一种海量、安全、低成本、高可靠的云存储服务,适合存放任意类型的文件。容量和处理能力弹性扩展,多种存储类型供选择,全面优化存储成本。它还能根据设置API来进行处理上传的图片,比如上传图片加水印、图片压缩等功能,但这些额外的功能一般来说不同服务商都会进行不同的收费,x千次0.x元等等。
阿里云对象存储服务称为OSS,而华为对象存储服务称为OBS,腾讯云对象存储服务称为COS,尽管每家公司的缩写名称不一样,但其实都是一种服务.
首先学习OSS之前必须要拥有一个阿里的对象存储OSS服务,所以需要提前购买阿里一个对象存储服务,这儿操作介绍跳过,毕竟花钱谁不会呀?不会找服务商呀。
这里主要讲述其阿里云对象存储服务OSS的JAVA API使用方法.
基本概念
OSS有如下几个产品参数概念:
Region(地域)
Region表示OSS的数据中心所在物理位置。一般来说,距离用户更近的Region访问速度更快。
Endpoint(访问域名)
Endpoint表示OSS对外服务的访问域名。OSS以HTTP RESTful API的形式对外提供服务,当访问不同的Region的时候,需要不同的域名。通过内网和外网访问同一个Region所需要的Endpoint也是不同的。
AccessKey(访问密钥)
AccessKey简称AK,指的是访问身份验证中用到的AccessKeyId和AccessKeySecret,AccessKeyId用于标识用户;AccessKeySecret是用户用于加密签名字符串和OSS用来验证签名字符串的密钥,必须保密。
Bucket(存储空间)
存储空间是用户用于存储对象(Object)的容器,所有的对象都必须隶属于某个存储空间。存储空间具有各种配置属性,包括地域、访问权限、存储类型等。
对象(Object)
对象是OSS存储数据的基本单元,也被称为OSS的文件。和传统的文件系统不同,对象没有文件目录层级结构的关系。对象由元信息(Object Meta),用户数据(Data)和文件名(Key)组成,并且由存储空间内部唯一的Key来标识。
OSS与文件系统的对比
对比项 | OSS | 文件系统 |
---|---|---|
数据模型 | OSS是一个分布式的对象存储服务,提供的是一个Key-Value对形式的对象存储服务。 | 文件系统是一种典型的树状索引结构。 |
数据获取 | 根据Object的名称(Key)唯一的获取该Object的内容。虽然用户可以使用类似test1/test.jpg的名字,但是这并不表示用户的Object是保存在test1目录下面的。对于OSS来说,test1/test.jpg仅仅只是一个字符串,和a.jpg这种并没有本质的区别。因此不同名称的Object之间的访问消耗的资源是类似的。 | 一个名为test1/test.jpg的文件,访问过程需要先访问到test1这个目录,然后再在该目录下查找名为test.jpg的文件。 |
优势 | 支持海量的用户并发访问。 | 支持文件的修改,比如修改指定偏移位置的内容、截断文件尾部等。也支持文件夹的操作,比如重命名目录、删除目录、移动目录等非常容易。 |
由上可见,OSS服务获取数据类似Nosql读取方式(Map方式),本质是从各个存储表(Bucket)中进行存储.
Java API使用
Maven导入
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.10.2</version>
</dependency>
如果使用的是Java 9及以上的版本,则需要添加jaxb相关依赖。添加jaxb相关依赖示例代码如下:
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<!-- no more than 2.3.3-->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.3</version>
</dependency>
创建SysConfigOss DTO类,用作Springboot配置信息注入
@Component
//自动配置文件属性名
@ConfigurationProperties(prefix = "sysConfig.oss")
public class SysConfigOss {
private String domain;
private String endpoint;
private String accessKeyId;
private String accessKeySecret;
private String bucketName;
private String diskImage;
private String diskSource;
private boolean personal;
...setting and getting methods...
}
在application.properties 或者application.yaml文件下配置相关OSS服务信息
sysConfig:
oss:
domain: XXX
endpoint: XXX
accessKeyId: XXX
accessKeySecret: XXX
bucketName: XXX
diskImage: XXX
diskSource: XXX
personal: XXX
配置OssComponent组件
@Component
public class OssComponent {
@Autowired
private SysConfigOss sysConfigOss;
@Autowired
private PathComponent pathComponent;
/**
* 初始化OSS实体类
* @return
*/
private OSS init() {
return new OSSClientBuilder().build(sysConfigOss.getEndpoint(), sysConfigOss.getAccessKeyId(), sysConfigOss.getAccessKeySecret());
}
/**
* OSS对象存储
*
* @param inputStream
* @param diskName
* @param fileName
* @return
*/
private String uploadObject2OSS(InputStream inputStream, String diskName, String fileName) {
String resultStr = null;
OSS ossClient = init();
PutObjectResult putObjectResult = ossClient.putObject(sysConfigOss.getBucketName(), diskName + "/" + fileName, inputStream);
ossClient.shutdown();
return putObjectResult.getETag();
}
private String generateStorageName(String fileName) {
return DateUtil.today()+"/"+System.currentTimeMillis() + "_" + fileName;
}
/**
* 存储图片文件 返回数据库文件名
*
* @param file
* @return
* @throws IOException
*/
public String storeImage(MultipartFile file) throws IOException {
String fileName = ValidateUtil.isEmpty(file.getOriginalFilename()) ? "auto" : file.getOriginalFilename();
String storageName = generateStorageName(fileName);
uploadObject2OSS(file.getInputStream(), sysConfigOss.getDiskImage(), storageName);
return pathComponent.getImgDbFileName(storageName);
}
/**
* 存储素材文件 返回数据库文件名
*
* @param file
* @return
* @throws IOException
*/
public String storeSource(MultipartFile file) throws IOException {
String fileName = ValidateUtil.isEmpty(file.getOriginalFilename()) ? "auto" : file.getOriginalFilename();
String storageName = generateStorageName(fileName);
uploadObject2OSS(file.getInputStream(), sysConfigOss.getDiskSource(), storageName);
return pathComponent.getSourceDbFileName(storageName);
}
/**
* 获取私有链接,用于文件/图片回显等
* @param dbFileName
* @return
*/
public String getPrivateAccessUrl(String dbFileName) {
OSS ossClient = init();
Date expiration = new Date(new Date().getTime() + 3600 * 1000);
GeneratePresignedUrlRequest generatePresignedUrlRequest ;
generatePresignedUrlRequest =new GeneratePresignedUrlRequest(sysConfigOss.getBucketName(), dbFileName);
generatePresignedUrlRequest.setExpiration(expiration);
URL url = ossClient.generatePresignedUrl(generatePresignedUrlRequest);
return url.toString();
}
}
- 通过使用OSS.putObject方法,存储对象.
- 对于私有的OSS服务,通过使用创建GeneratePresignedUrlRequest对象再调用OSS.generatePresignedUrl方法获取私有链接,来获取存储的对象.
- 对于公开读取的OSS服务,直接使用配置的domain+文件位置+文件名即可获取存储对象