OSS对象存储服务

OSS简介

  • 阿里云对象存储服务(Object Storage Service,简称OSS),是阿里云对外提供的海量、安全、低成本、高可靠的云存储服务。通过提供的简单的REST接口,在任何时间、任何地点、任何互联网设备上进行上传和下载数据。基于OSS,可以搭建出各种多媒体分享网站、网盘、个人和企业数据备份等基于大规模数据的服务
  • 简单来说,OSS就是一个可以上传、下载、分享文件的服务,这一点从实用意义上来说与网盘是差不多的。OSS相比较网盘的优点在于其数据安全性更高(数据多重冗余备份,不易丢失)、使用可靠性更高(上下行速度等皆有保障),同时其还提供API接口和丰富的SDK包,而其缺点是带来一定的使用成本,但是目前此成本还是很低的。在今天,很多免费网盘都倒下了,有些网盘走向付费使用的道路,而其安全、可靠性又没有得到有效的提高,这也使得OSS的优势更加明显
  • 参考阿里云官网什么是对象存储OSS
  • CSDN博文《阿里云OSS(对象存储服务)简介》:https://blog.csdn.net/m0_37897502/article/details/80702805

开通OSS云存储服务

资源包购买

  • 首先去阿里云购买对象存储OSS资源包:https://www.aliyun.com/product/oss/
  • 有两种方式
    • 第一种是【按量收费】,只需要开通OSS,就可以直接用OSS服务了,不需要付款什么的,按量收费,从我们的阿里云账户直接扣钱,边用边扣的模式
    • 还有一种是【买套餐包月包年】,需要我们到页面付款一次结清

只供学习的话推荐默认标准型存储包5元半年即可

创建Bucket

  • 然后在控制台新建Bucket。Bucket的作用:相当于一个存储图片的仓库。然后下图就是配置仓库的信息,我们通过这个仓库的信息把图片上传到这个仓库里面

上传图片

  • 在【文件管理】中,可直接上传图片,在浏览器访问到https://origins-xiaoliblog.oss-cn-shanghai.aliyuncs.com/headerimg.jpg

  • 在【数据处理】->【图片处理】中,可添加水印的样式

  • 在【图片处理】下的【访问设置】中,选择自定义分隔符,在图片路径后拼接分隔符与水印的规格名称,就能给图片添加上水印
  • 开启【原图保护功能】的话,如果把路径后的水印规则给去掉,就不能访问该图片了

PicGo实现上传图片

下载PicGo

添加用户

  • 推荐最好是单独创建一个用户来单独操作OSS(用户的定义就是需要访问云资源的人员或应用程序),这样给这个用户赋予单独的访问OSS的权限,更加安全方便
  • 进入【RAM访问控制】-【人员管理】-【用户】-【新建用户】
  • 之后进行用户配置,注意要勾选【编程访问】,控制台密码登录可以不选择,登录名称,显示名称自己设定,如下图所示:

  • 确定后得到创建用户的信息,这里要记下AccessKey IDAccessKey Secret,之后配置PICGO用到,因为这个界面关掉之后就不好找了,所以最好记在记事本里
  • 如果忘了可以点击用户登录名称,然后找到【用户AccessKey】创建AccessKey,重新获取AccessKey IDAccessKey Secret

  • 设置【用户权限】,使得用户只能访问OSS的服务。点击添加权限,如下图所示:

配置图床

  • 需要参数AccesskeyAccesskeySecret
  • 存储空间名就是Bucket的名字
  • 存储区域到阿里云OSS控制台去找,例如下图中存储区域就是 oss-cn-shanghai

  • 存储路径是存储图片的位置,要求以/结尾。
  • 自定义域名可以不填写

配置Typora

  • 首先在PicGo开启服务,注意端口号为本地

  • 然后配置Typora连接PicGO图床

Java实现图片上传

简单上传

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<!-- 阿里云oss -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.10.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<!--文件上传-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<!--上传阿里云OSS-->
<!-- https://mvnrepository.com/artifact/org.jdom/jdom -->
<dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom</artifactId>
<version>2.0.2</version>
</dependency>

参数常量封装

  • 创建一个用于封装常量的类OSSClientConstants,便于修改
1
2
3
4
5
6
7
8
9
10
11
12
13
//阿里云OSS参数常量类
public class OSSClientConstants {
//阿里云API的外网域名 以上海为例,其他按情况填写
public static final String ENDPOINT = "oss-cn-shanghai.aliyuncs.com";
//阿里云API的密钥Access Key ID
public static final String ACCESS_KEY_ID = "<yourAccessKeyId>";
//阿里云API的密钥Access Key Secret
public static final String ACCESS_KEY_SECRET = "<yourAccessKeySecret>";
//阿里云API的bucket名称
public static final String BUCKET_NAME = "origins-xiaoliblog";
//Bucket 域名即外网访问的域名
public static final String BUCKET_URL= "http://origins-xiaoliblog.oss-cn-shanghai.aliyuncs.com/";
}

构建工具类

  • 构建一个工具类AliyunOSSClientUtil用于封装对OSS对象存储的操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
@Component //实例化 便于在控制器中自动装配
public class AliyunOSSClientUtil {
//阿里云API的内或外网域名
private static String ENDPOINT;
//阿里云API的密钥Access Key ID
private static String ACCESS_KEY_ID;
//阿里云API的密钥Access Key Secret
private static String ACCESS_KEY_SECRET;
//阿里云API的bucket名称
private static String BUCKET_NAME;
//Bucket 域名即外网访问的域名
private static String BUCKET_URL;
//日期格式化对象
private static SimpleDateFormat SDF = new SimpleDateFormat("yyyymmdd"); //日期格式化对象
//初始化属性
static {
ENDPOINT = OSSClientConstants.ENDPOINT;
ACCESS_KEY_ID = OSSClientConstants.ACCESS_KEY_ID;
ACCESS_KEY_SECRET = OSSClientConstants.ACCESS_KEY_SECRET;
BUCKET_NAME = OSSClientConstants.BUCKET_NAME;
BUCKET_URL = OSSClientConstants.BUCKET_URL;
}

/**
* 获取阿里云OSS客户端对象
* @return ossClient
*/
public OSSClient getOSSClient() {
//创建一个OSSClient对象
OSSClient ossClient = new OSSClient(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
//通过连接对象判断Bucket仓库是否存在
if(ossClient.doesBucketExist(BUCKET_NAME)){
System.out.println(BUCKET_NAME+"仓库存在");
}else{
//如果没有就通过API接口创建Bucket仓库
System.out.println("Bucket不存在,创建新的Bucket:"+BUCKET_NAME);
CreateBucketRequest bucketRequest = new CreateBucketRequest(null);
//设置Bucket名称
bucketRequest.setBucketName(BUCKET_NAME);
//设置权限:公共读
bucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
//创建新Bucket
ossClient.createBucket(bucketRequest);
}
return ossClient;
}

/**
* 创建模拟文件夹
* @param ossClient oss连接
* @param bucketName 存储空间
* @param folder 模拟文件夹名如"qj_nanjing/"
* @return 文件夹名
*/
public String createFolder(OSSClient ossClient,String bucketName,String folder) {
//判断文件夹是否存在,不存在则创建
if(!ossClient.doesObjectExist(bucketName,folder)){
//创建文件夹
ossClient.putObject(bucketName,folder,new ByteArrayInputStream(new byte[0]));
System.out.println("创建文件夹成功");
//得到文件夹名
OSSObject ossObject = ossClient.getObject(bucketName,folder);
String fileDir = ossObject.getKey();
System.out.println("文件名为:"+fileDir);
return fileDir;
}
return folder;
}

/**
* 上传图片至OSS
*
* @param multipartFile 文件对象F
* @param FileType 文件类型F
* @return url 返回文件访问路径
*/
//MultipartFile是一个封装了文件信息的对象
public String uploadDocument(MultipartFile multipartFile,String FileType){
//获得OSS连接
OSSClient ossClient = this.getOSSClient();
//获取文件的后缀
String suffix = multipartFile.getOriginalFilename();
suffix = suffix.substring(suffix.lastIndexOf(".")); //.后面的
//获得当前上传日期
String date = SDF.format(new Date());
//通过UUID名来避免文件重名
String uuid = UUID.randomUUID().toString().replace("-","");
//组合文件名称
String filename = FileType + "/" + date + "/" + uuid + suffix;
String url = null;
//通过OSSClient获得上传文件后返回的url
try {
ossClient.putObject(BUCKET_NAME,filename,new ByteArrayInputStream(multipartFile.getBytes()));
url = BUCKET_URL + filename;
} catch (Exception e) {
e.printStackTrace();
}finally {
//关闭连接
ossClient.shutdown();
}
return url;
}

/**
* 通过文件名判断并获取OSS服务文件上传时文件的contentType
* @param multipartFile 文件对象
* @return 文件的contentType
*/
public String getContentType(MultipartFile multipartFile){
//获取文件的后缀
String suffix = multipartFile.getOriginalFilename();
suffix = suffix.substring(suffix.lastIndexOf(".")); //.后面的
if(".bmp".equalsIgnoreCase(suffix)) {
return "image/bmp";
}
if(".gif".equalsIgnoreCase(suffix)) {
return "image/gif";
}
if(".jpeg".equalsIgnoreCase(suffix) || ".jpg".equalsIgnoreCase(suffix) || ".png".equalsIgnoreCase(suffix) ) {
return "image/jpeg";
}
if(".html".equalsIgnoreCase(suffix)) {
return "text/html";
}
if(".txt".equalsIgnoreCase(suffix)) {
return "text/plain";
}
if(".vsd".equalsIgnoreCase(suffix)) {
return "application/vnd.visio";
}
if(".ppt".equalsIgnoreCase(suffix) || "pptx".equalsIgnoreCase(suffix)) {
return "application/vnd.ms-powerpoint";
}
if(".doc".equalsIgnoreCase(suffix) || "docx".equalsIgnoreCase(suffix)) {
return "application/msword";
}
if(".xml".equalsIgnoreCase(suffix)) {
return "text/xml";
}
//默认返回类型
return "image/jpeg";
}
}

接口测试

  • 客户端代码
1
2
3
4
5
6
7
<fieldset>
<legend>文件上传</legend>
<form action="upload" method="post" enctype="multipart/form-data">
文件提交:<input type="file" name="file" size="20"/><br/>
<input type="submit" value="提交"/>
</form>
</fieldset>
  • 创建控制器UploadController用于接收前端请求并调用工具类
1
2
3
4
5
6
7
8
9
10
11
12
13
@Controller
public class UploadController {
@Autowired
AliyunOSSClientUtil ossClientUtil;
@RequestMapping("/upload")
@ResponseBody //JSON字符串格式 RequestParm为了使其和表单的name一致
public String uploadtest(@RequestParam("file") MultipartFile multipartFile){
String FileType = ossClientUtil.getContentType(multipartFile);
String url = ossClientUtil.uploadDocument(multipartFile,FileType);
System.out.println("路径:"+url);
return "文件上传成功!";
}
}