一、开通阿里云OSS功能并创建RAM账号
1、首先必须要了解的几个关于OSS的概念:
https://help.aliyun.com/document_detail/31947.html
| 中文 | 英文 | 说明 |
| 存储空间 | Bucket | 存储空间是您用于存储对象(Object)的容器,所有的对象都必须隶属于某个存储空间。 |
| 对象/文件 | Object | 对象是 OSS 存储数据的基本单元,也被称为OSS的文件。对象由元信息(Object Meta)、用户数据(Data)和文件名(Key)组成。对象由存储空间内部唯一的Key来标识。 |
| 地域 | Region | 地域表示 OSS 的数据中心所在物理位置。您可以根据费用、请求来源等综合选择数据存储的地域。详情请查看OSS已经开通的Region。 |
| 访问域名 | Endpoint | Endpoint 表示OSS对外服务的访问域名。OSS以HTTP RESTful API的形式对外提供服务,当访问不同地域的时候,需要不同的域名。通过内网和外网访问同一个地域所需要的域名也是不同的。具体的内容请参见各个Region对应的Endpoint。 |
| 访问秘钥 | AccessKey | AccessKey,简称 AK,指的是访问身份验证中用到的AccessKeyId 和AccessKeySecret。OSS通过使用AccessKeyId 和AccessKeySecret对称加密的方法来验证某个请求的发送者身份。AccessKeyId用于标识用户,AccessKeySecret是用户用于加密签名字符串和OSS用来验证签名字符串的密钥,其中AccessKeySecret 必须保密。 |
2、新增Bucket

创建成功:

Bucket管理界面如下:

3、开通RAM访问控制
https://help.aliyun.com/product/28625.html

创建完成后,必须要记得“添加权限”

之后,这个“AccessKey ID”和“SECRET”对就可以被正常使用了!
二、通过SDK上传文件——简单上传
https://help.aliyun.com/document_detail/32013.html
1、在maven中添加依赖:
<dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId> <version>3.8.0</version> </dependency>
2、测试代码如下:
@Test
public void testUpload1() throws FileNotFoundException {
// Endpoint以杭州为例,其它Region请按实际情况填写。
String endpoint = "oss-cn-shanghai.aliyuncs.com";
// 云账号AccessKey有所有API访问权限,建议遵循阿里云安全最佳实践,创建并使用RAM子账号进行API访问或日常运维。
String accessKeyId = "LTAI4GG4TR1dMsFQU";
String accessKeySecret = "eJb8sWZUSk1ONpftVN";
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
// 上传文件流。
InputStream inputStream = new FileInputStream("C:\\Users\\jigq\\Desktop\\子丹商城\\2\\2.jpg");
ossClient.putObject("zidanmall", "2.jpg", inputStream);
// 关闭OSSClient。
ossClient.shutdown();
System.out.println("上传成功。。。");
}
3、测试结果:
简单上传成功!
三、SpringCloud Alibaba-OSS 服务上传
https://github.com/alibaba/spring-cloud-alibaba/blob/master/README-zh.md
1、引入springcloud alibaba oss的maven依赖
<!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alicloud-oss --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alicloud-oss</artifactId> <version>2.1.0.RELEASE</version> </dependency>
2、在application.yml中增加配置信息:
spring: cloud: alicloud: access-key: LTAI4GG4TR1dMsFQU226sb6h secret-key: eJb8sWZUSk1ONpftVNa287jns8KZGp oss: endpoint: oss-cn-shanghai.aliyuncs.com
3、测试代码将变得更加简单:
@Test
public void testUpload2() throws FileNotFoundException {
// 上传文件流。
InputStream inputStream = new FileInputStream("C:\\Users\\jigq\\Desktop\\子丹商城\\2\\3.jpg");
ossClient.putObject("zidanmall", "3.jpg", inputStream);
// 关闭OSSClient。
ossClient.shutdown();
System.out.println("上传成功。。。");
}
测试成功!
四、最佳实践——服务端签名后直传
实际应用中,Web端向服务端请求签名,然后直接上传,不会对服务端产生压力,而且安全可靠;

结合zidanmall,我们将所有的第三方服务,做成一个 zidanmall-third-party 模块:
1、pom.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.jiguiquan.zidanmall</groupId>
<artifactId>zidanmall-third-party</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>zidanmall-third-party</name>
<description>子丹商城-所有的第三方服务继承模块</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR3</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>com.jiguiquan.zidanmall</groupId>
<artifactId>zidanmall-common</artifactId>
<version>1.0-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alicloud-oss</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2、bootstrap.yml:
server: port: 30000 spring: application: name: zidanmall-third-party cloud: nacos: discovery: server-addr: localhost:8848 config: server-addr: localhost:8848 file-extension: yaml namespace: f2e98e0e-63ec-44f5-8a9f-fdc797ab22bf group: dev refresh-enabled: true
3、application.yml:
spring: cloud: alicloud: access-key: LTAI4GG4TR1dMsFQU226sb6h secret-key: eJb8sWZUSk1ONpftVNa287jns8KZGp oss: endpoint: oss-cn-shanghai.aliyuncs.com bucket: zidanmall
4、返回签名的核心代码:
https://help.aliyun.com/document_detail/91868.html
@RestController
public class OssController {
@Autowired
private OSS ossClient;
@Value("${spring.cloud.alicloud.oss.bucket}")
private String bucket;
@Value("${spring.cloud.alicloud.oss.endpoint}")
private String endpoint;
@Value("${spring.cloud.alicloud.access-key}")
private String accessId;
/**
*
* @return
*/
@GetMapping("/oss/policy")
public R policy(){
String host = "https://" + bucket + "." + endpoint; // host的格式为 bucketname.endpoint
// callbackUrl为 上传回调服务器的URL,请将下面的IP和Port配置为您自己的真实信息。
// String callbackUrl = "http://88.88.88.88:8888";
String format = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
String dir = format + "/"; // 用户上传文件时自定义的目录文件夹。
try {
long expireTime = 30;
long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
Date expiration = new Date(expireEndTime);
// PostObject请求最大可支持的文件大小为5 GB,即CONTENT_LENGTH_RANGE为5*1024*1024*1024。
PolicyConditions policyConds = new PolicyConditions();
policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);
String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
byte[] binaryData = postPolicy.getBytes("utf-8");
String encodedPolicy = BinaryUtil.toBase64String(binaryData);
String postSignature = ossClient.calculatePostSignature(postPolicy);
Map<String, String> respMap = new LinkedHashMap<String, String>();
respMap.put("accessid", accessId);
respMap.put("policy", encodedPolicy);
respMap.put("signature", postSignature);
respMap.put("dir", dir);
respMap.put("host", host);
respMap.put("expire", String.valueOf(expireEndTime / 1000));
return new R().put("data", respMap);
} catch (Exception e) {
System.out.println(e.getMessage());
return null;
}
}
}
5、最后,我们使用 Gateway做一下统一的路由转发:
spring:
cloud:
gateway:
routes:
- id: third_party_route
uri: lb://zidanmall-third-party
predicates:
- Path=/api/thirdparty/**
filters:
- RewritePath=/api/thirdparty/(?<segment>/?.*), /$\{segment}
6、都完成后,我们通过网关访问一下此接口,看看是否能正常访问:

显然是OK的,这样我们的OSS服务端签名接口就完成了;
五、最后补充一点
当我们前端从后端获取到签名后,会直接调用阿里云的接口进行文件上传;
但是由于阿里云的接口并没有经过我们的Gateway统一进行跨域允许设置,所以会碰到跨域问题;
所以我们必须要开启阿里云OSS文件上传的跨域支持:创建跨域规则:

这样,我们整个的OSS最佳实践的文件上传功能就算是实现了后端部分,与前端部分的整合,可以参见:
商品服务-品牌管理-三、使用阿里云OSS服务实现logo文件的上传



