SpringCloud alibaba OSS对象存储服务的使用

1. 开通

参看官网即可

2. 使用

2.1 原生使用

2.1.1 引入SDK依赖

<!-- 添加阿里云OSS对象存储服务SDK API -->
<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>3.10.2</version>
</dependency>

<!-- 添加依赖管理 -->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>2.1.0.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

2.1.2 上传API

// Endpoint以杭州为例,其它Region请按实际情况填写。
String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
// 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。
String accessKeyId = "<yourAccessKeyId>";
String accessKeySecret = "<yourAccessKeySecret>";

// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

// 创建PutObjectRequest对象。
PutObjectRequest putObjectRequest = new PutObjectRequest("<yourBucketName>", "<yourObjectName>", new File("<yourLocalFile>"));

// 如果需要上传时设置存储类型与访问权限,请参考以下示例代码。
// ObjectMetadata metadata = new ObjectMetadata();
// metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
// metadata.setObjectAcl(CannedAccessControlList.Private);
// putObjectRequest.setMetadata(metadata);

// 上传文件。
ossClient.putObject(putObjectRequest);

// 关闭OSSClient。
ossClient.shutdown();  

2.2 使用SpringCloud Alibaba-OSS

2.2.1 简介

    对象存储服务(Object Storage Service,OSS)是一种海量、安全、低成本、高可靠的云储存服务,适合存放任意类型的文件,容量和处理能力弹性扩展,多种存储类型供选择,全面优化存储成本。

2.2.2 使用

1)引入依赖

<!-- 导入 springCloud Alibaba SSO 依赖 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alicloud-oss</artifactId>
</dependency>


<!-- 添加依赖管理 -->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>2.1.0.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

2)配置

  cloud:
    alicloud:
      access-key: ` 你的access-key `
      secret-key: ` 你的secret-key `
      oss:
        endpoint: ` 你的oss endpoint `

3)调用

@Autowired
private OSSClient ossClient;

@Test
public void test02() throws FileNotFoundException {
    InputStream in = new FileInputStream("D:\\1.jpg");
    ossClient.putObject("zoudm-gulimall", "1.png",in);
    ossClient.shutdown();
}

查看OSS文件列表,如图;

至此,基本的OSS对象存储服务的简单使用就完成了。

3. 阿里云对象云存储——服务端签名后直传

        上面的基本使用方式可以实现文件的云存储,但是,需要文件经过我们的服务器,会存在性能瓶颈,同时也很麻烦,我们可以通过服务端返回签名,浏览器直接将文件流上传到阿里云OSS。

说明:将所有的第三方服务都集成在一个工程中,方便统一管理,针对OSS存储功能,也是新建一个工程。

官方参考手册:https://help.aliyun.com/document_detail/32009.html?spm=a2c4g.11186623.6.771.13e759aa7vJ34d

参看最佳实践,如图:

3.1 操作步骤

3.1.1 引入依赖

1)OSS依赖

<!-- 导入 springCloud Alibaba SSO 依赖 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alicloud-oss</artifactId>
</dependency>


<!-- 添加依赖管理 -->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>2.1.0.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

2)Nacos等依赖

3.1.2 应用服务器信息配置

1)OOS对象存储服务信息配置

将OSS的基本信息配置单独抽取成一个配置文件,在nacos配置中心中配置,如图;

2)配置中心配置项

bootstra.properties

# 配置中心服务名
spring.cloud.nacos.config.name=third-party

## 指定Nacos配置中心的地址(就是Nacos Server的地址)
spring.cloud.nacos.config.server-addr=127.0.0.1:8848

# 指定名称空间
spring.cloud.nacos.config.namespace=6d1d7b7d-db3a-457f-afdd-5772d4bbbf8a

# OSS配置文件的data-id
spring.cloud.nacos.config.ext-config[0].data-id=oss.yml
# OSS 配置文件所属分组
spring.cloud.nacos.config.ext-config[0].group=dev
# 配置文件更改之后,动态刷新
spring.cloud.nacos.config.ext-config[0].refresh=true

## 指定 配置分组(不指定默认是DEFAULT_GROUP)
spring.cloud.nacos.config.group=dev

3)配置注册中心配置项

application.yml

spring:
  application:
    name: gulimall-third-party      # 注册中心服务名
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848   # 注册中心地址
    #alicloud:                         # OSS对象存储服务   配置单独抽取在Nacos中了
    #  access-key: LTAI4GHUksgffSgTD1FKbwkm
    #  secret-key: nLLv4x0a2TCY9L8F4hMrRT9Y7mhLnF
    #  oss:
    #    endpoint: oss-cn-hangzhou.aliyuncs.com

server:
  port: 9000

注意:该服务引用了common工程,common工程中有mybatis-plus依赖,如果三方服务不需要数据库支持,那么需要将mybatis-plus依赖排除掉

<dependency>
    <groupId>com.bjc.gulimall</groupId>
    <artifactId>gulimall-common</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <!-- 因为目前该服务不需要数据库相关信息,所以在配置文件中不会配置数据库相关信息,所以这里将mybatis-plus启动器排除掉 -->
    <exclusions>
        <exclusion>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </exclusion>
    </exclusions>
</dependency>

4)测试

package com.bjc.gulimall.thirdparty;

import com.aliyun.oss.OSSClient;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

@SpringBootTest
@RunWith(SpringRunner.class)
public class GulimallThirdPartyApplicationTests {

    @Autowired
    private OSSClient ossClient;

    @Test
    public void test02() throws FileNotFoundException {
        InputStream in = new FileInputStream("D:\\1.jpg");
        ossClient.putObject("zoudm-gulimall", "2.png",in);
        ossClient.shutdown();
    }

}

查看OSS文件列表,如图:

这样就表示服务可以正常读取Nacos配置中心的配置文件了。

3.1.2 签名信息获取

package com.bjc.gulimall.thirdparty.controller;

import com.aliyun.oss.OSS;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.PolicyConditions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;

@RestController
public class OosController {

    @Autowired
    private OSS ossClient;

    @Value("${spring.cloud.alicloud.oss.endpoint}")
    private String endpoint;

    @Value("${spring.cloud.alicloud.access-key}")
    private String accessId;

    @Value("${spring.cloud.alicloud.oss.bucket}")
    private String bucket;

    @RequestMapping("/oss/policy")
    protected Map<String, String> policy(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        // https://zoudm-gulimall.oss-cn-hangzhou.aliyuncs.com/1.png
        String host = "https://" + bucket + "." + endpoint; // host的格式为 bucketname.endpoint
        // callbackUrl为 上传回调服务器的URL,请将下面的IP和Port配置为您自己的真实信息。
        // String callbackUrl = "http://88.88.88.88:8888";
        String fileDir = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        String dir = fileDir + "/"; // 用户上传文件时指定的前缀。  当天上传的文件放在当天日期命名的目录下

        Map<String, String> respMap = new LinkedHashMap<String, String>();
        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);


            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));
            // respMap.put("expire", formatISO8601Date(expiration));

            /***  下面的代码是处理跨域的,因为我们跨域在网关统一解决,所以方法不用返回void   直接返回map即可
                JSONObject jasonCallback = new JSONObject();
                jasonCallback.put("callbackUrl", callbackUrl);
                jasonCallback.put("callbackBody",
                        "filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}");
                jasonCallback.put("callbackBodyType", "application/x-www-form-urlencoded");
                String base64CallbackBody = BinaryUtil.toBase64String(jasonCallback.toString().getBytes());
                respMap.put("callback", base64CallbackBody);

                JSONObject ja1 = JSONObject.fromObject(respMap);
                // System.out.println(ja1.toString());
                response.setHeader("Access-Control-Allow-Origin", "*");
                response.setHeader("Access-Control-Allow-Methods", "GET, POST");
                response(request, response, ja1.toString());
             */
        } catch (Exception e) {
            // Assert.fail(e.getMessage());
            System.out.println(e.getMessage());
        } finally {
            ossClient.shutdown();
        }

        return respMap;
    }

}

注意:这里如果自动注入OSSClient服务启动会报错,因为,OSS自动配置中使用的是接口OSS注入,所以这个地方需要使用OSS而不是OSSClient。

访问:结果如图:

3.1.3 配置网关(可选)

因为要让所有的请求都经过网关,所以这里配置网关,直接访问网关地址路由到该服务

配置如图:

再次访问:

至此,服务端签名完成

3.2 修改CORS(Bucket 跨域)

客户端进行表单直传到OSS时,会从浏览器向OSS发送带有Origin的请求消息。OSS对带有Origin头的请求消息会进行跨域规则(CORS)的验证。因此需要为Bucket设置跨域规则以支持Post方法。

操作步骤:

1)登录OSS管理控制台。
2)单击Bucket列表,之后单击目标Bucket名称。
3)单击权限管理 > 跨域设置,在跨域设置区域单击设置。


4)单击创建规则,配置如下图所示。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值