目录
3.2、common模块创建对应的实体类,并引入yml中的数据
3.4、在web模块中引入application-comm.yml
简介
1、什么是OSS呢?
阿里云控制台首页 (aliyun.com) 或者百度所有aliyun
「OSS」的英文全称是Object Storage Service,翻译成中文就是「对象存储服务」,官方一点解释就是对象存储是一种使用HTTP API存储和检索非结构化数据和元数据对象的工具。
白话文解释就是将系统所要用的文件上传到云硬盘上,该云硬盘提供了文件下载、上传等一列服务,这样的服务以及技术可以统称为OSS,业内提供OSS服务的厂商很多,知名常用且成规模的蓝队云等。
不但有aliyun的OSS存储服务,还有 腾讯云的OBS,腾讯云的COS等,都是可以通过SDK接口实现的。
2、aliyun的accessKey
创建好自己的accessKey一定要记好你的Key和Secret
3、OSS存储服务
创建一个自己的桶(Bucket) ,创建完成之后,点击你自己的桶名称,
点击概览,最后就会有一个endipint的域点
快速开始
OSS存储我分两个模块来讲解,第一种是单体架构,可以直接使用的快速开发,第二种是公司常用的分布式架构的OSS存储
1、引入依赖
<!-- OSS对象存储-->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.10.2</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
2、单体架构
package com.dongyimai.util;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.UUID;
public class OSSUtil implements Serializable {
public static String uploadFile(MultipartFile file) {
// Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
//在上述csdn中的OSS存储服务介绍了如何获取下面的4个信息
String endpoint = "自己存储服务的域点";
// 强烈建议不要把访问凭证保存到工程代码里,否则可能导致访问凭证泄露,威胁您账号下所有资源的安全。本代码示例以从环境变量中获取访问凭证为例。运行本代码示例之前,请先配置环境变量。
String accessKeyId = "自己的accessKey";
String accessKeySecret = "自己的accessKeySecret";
// 填写Bucket名称,例如examplebucket。
String bucketName ="自己的桶";
// 填写Object完整路径,例如exampledir/exampleobject.txt。Object完整路径中不能包含Bucket名称。
//防止重复覆盖设置随机数
String uuid= UUID.randomUUID().toString().replaceAll("-","");
// String objectName = imgPath;
//文件名就变为: 随机数+a.jpg
String fileName=uuid+file.getOriginalFilename();
String dataPath = LocalDate.now().toString();
String path = dataPath.replaceAll("-", "/");
fileName=path+"/"+fileName;
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint,accessKeyId,accessKeySecret);
try {
ossClient.putObject(bucketName, fileName,file.getInputStream());
//返回的图片路径 https://+bucketName名称+.+endpoint+objectName+/+fileName
String url="https://"+bucketName+"."+endpoint+"/"+fileName;
return url;
} 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());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
return null;
}
}
使用到单体架构,就直接当一个util文件使用即可。
下图就是上述代码,忽略即可
3、分布式架构
我的项目结构:将common模块作为工具模块,web启动类模块引入common依赖
3.1、在common模块中配置yml文件
application-comm.yml
#当前的yaml的名称为:application-comm.yml
oss:
endpoint: 自己的域点
accessKeyId: 自己的accessKeyId
accessKeySecret: 自己的accesskeySecret
bucketName: 自己的桶
3.2、common模块创建对应的实体类,并引入yml中的数据
package com.dongyimai.util;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.io.Serializable;
@Component
@ConfigurationProperties(prefix = "oss")
public class ConstantPropertiesUtils implements Serializable , InitializingBean {
//读取配置文件的内容
private String endpoint;
private String accessKeyId;
private String accessKeySecret;
private String bucketName;
public String getEndpoint() {
return endpoint;
}
public void setEndpoint(String endpoint) {
this.endpoint = endpoint;
}
public String getAccessKeyId() {
return accessKeyId;
}
public void setAccessKeyId(String accessKeyId) {
this.accessKeyId = accessKeyId;
}
public String getAccessKeySecret() {
return accessKeySecret;
}
public void setAccessKeySecret(String accessKeySecret) {
this.accessKeySecret = accessKeySecret;
}
public String getBucketName() {
return bucketName;
}
public void setBucketName(String bucketName) {
this.bucketName = bucketName;
}
@Override
public String toString() {
return "ConstantPropertiesUtils{" +
"endpoint='" + endpoint + '\'' +
", accessKeyId='" + accessKeyId + '\'' +
", accessKeySecret='" + accessKeySecret + '\'' +
", bucketName='" + bucketName + '\'' +
'}';
}
//定义公共静态常量
public static String END_POINT;
public static String ACCESS_KEY_ID;
public static String ACCESS_KEY_SECRET;
public static String BUCKET_NAME;
//在当前文件加载之后执行该方法
//这个方法的意义就是:将已经被加载好的属性设置到静态常亮中,方便调用
@Override
public void afterPropertiesSet() throws Exception {
END_POINT = endpoint;
ACCESS_KEY_ID = accessKeyId;
ACCESS_KEY_SECRET = accessKeySecret;
BUCKET_NAME = bucketName;
}
}
注意:使用@ConfigurationProperties(prefix = "XXX")时,在springboot或者spring项目启动之后才会加载执行!
3.3、common模块创建OSSUtil工具类
package com.dongyimai.util;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.UUID;
public class OSSUtil implements Serializable {
public static String uploadFile(MultipartFile file) {
// Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
String endpoint = ConstantPropertiesUtils.END_POINT;
// 强烈建议不要把访问凭证保存到工程代码里,否则可能导致访问凭证泄露,威胁您账号下所有资源的安全。本代码示例以从环境变量中获取访问凭证为例。运行本代码示例之前,请先配置环境变量。
String accessKeyId = ConstantPropertiesUtils.ACCESS_KEY_ID;
String accessKeySecret = ConstantPropertiesUtils.ACCESS_KEY_SECRET;
// 填写Bucket名称,例如examplebucket。
String bucketName = ConstantPropertiesUtils.BUCKET_NAME;
// 填写Object完整路径,例如exampledir/exampleobject.txt。Object完整路径中不能包含Bucket名称。
//防止重复覆盖设置随机数
String uuid= UUID.randomUUID().toString().replaceAll("-","");
// String objectName = imgPath;
//文件名就变为: 随机数+a.jpg
String fileName=uuid+file.getOriginalFilename();
String dataPath = LocalDate.now().toString();
String path = dataPath.replaceAll("-", "/");
fileName=path+"/"+fileName;
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint,accessKeyId,accessKeySecret);
try {
ossClient.putObject(bucketName, fileName,file.getInputStream());
//返回的图片路径 https://+bucketName名称+.+endpoint+objectName+/+fileName
String url="https://"+bucketName+"."+endpoint+"/"+fileName;
return url;
} 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());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
return null;
}
}
3.4、在web模块中引入application-comm.yml
因为涉及到两个模块时,当主启动类模块加载后,他的application.yml配置文件会覆盖掉子模块common中的application.yml,所以,我们给common模块中的yml改名称 applicaiton-comm.yml然后让主启动类application.yml模块中的yml引入即可:只引入-后边的名称就行
spring:
profiles:
include: comm
3.5、测试
@PostMapping("/upload")
public ResultSet<String> upload( MultipartFile file){
System.out.println("file="+file);
String s = OSSUtil.uploadFile(file);
//会获取到一个存储到OSS中的路径连接,可以直接通过百度查看图片
System.out.println(s);
return ResultSet.successData(s);
}