• gulimall基础篇回顾Day-08


    前言

    在这里插入图片描述
    文件存储大致分为以上三种方式:普通文件上传,普通文件的分布式情况,文件存储服务。
    普通文件上传: 单体应用或小项目可以部署在一个服务器上,浏览器发送上传文件的请求将文件存储在项目中的某个位置,如下次要用到此文件浏览器可以发送请求给服务器,服务器返回此文件进行展示。

    普通文件的分布式情况: 分布式情况下,商品服务分布在不同的服务器上。若只将文件存储在A服务器中,下次浏览器的请求被负载均衡到B服务器,则浏览器访问不到文件。

    文件存储服务: 无论浏览器发到那个服务进行文件上传,最终将上传的文件统一存储在文件存储系统中例如自建的服务器,云存储服务(阿里云,七牛云等)。本文记录阿里云对象存储服务OSS相关知识。

    一、OSS相关概念

    存储类型(Storage Class)
    OSS提供标准、低频访问、归档、冷归档四种存储类型,全面覆盖从热到冷的各种数据存储场景。其中标准存储类型提供高持久、高可用、高性能的对象存储服务,能够支持频繁的数据访问;低频访问存储类型适合长期保存不经常访问的数据(平均每月访问频率1到2次),存储单价低于标准类型;归档存储类型适合需要长期保存(建议半年以上)的归档数据;冷归档存储适合需要超长时间存放的极冷数据。更多信息,请参见存储类型介绍。

    存储空间(Bucket)
    存储空间是您用于存储对象(Object)的容器,所有的对象都必须隶属于某个存储空间。存储空间具有各种配置属性,包括地域、访问权限、存储类型等。您可以根据实际需求,创建不同类型的存储空间来存储不同的数据。

    对象(Object)
    对象是OSS存储数据的基本单元,也被称为OSS的文件。对象由元信息(Object Meta)、用户数据(Data)和文件名(Key)组成。对象由存储空间内部唯一的Key来标识。对象元信息是一组键值对,表示了对象的一些属性,例如最后修改时间、大小等信息,同时您也可以在元信息中存储一些自定义的信息。

    地域(Region)
    地域表示OSS的数据中心所在物理位置。您可以根据费用、请求来源等选择合适的地域创建Bucket。更多信息,请参见OSS已开通的地域。

    访问域名(Endpoint)
    Endpoint表示OSS对外服务的访问域名。OSS以HTTP RESTful API的形式对外提供服务,当访问不同地域的时候,需要不同的域名。通过内网和外网访问同一个地域所需要的域名也是不同的。更多信息,请参见各个Region对应的Endpoint。

    访问密钥(AccessKey)
    AccessKey简称AK,指的是访问身份验证中用到的AccessKey ID和AccessKey Secret。OSS通过使用AccessKey ID和AccessKey Secret对称加密的方法来验证某个请求的发送者身份。AccessKey ID用于标识用户;AccessKey Secret是用户用于加密签名字符串和OSS用来验证签名字符串的密钥,必须保密。关于获取AccessKey的方法,请参见获取AccessKey。

    使用过程:
    在这里插入图片描述

    二、使用原生sdk步骤

    2.1 导入依赖

    <dependency>
        <groupId>com.aliyun.oss</groupId>
        <artifactId>aliyun-sdk-oss</artifactId>
        <version>3.5.0</version>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2.2 编写代码

        @Test
        public void testUpload() throws FileNotFoundException {
            //endPoint以杭州为例 其他Region请按实际情况填写
            String endPoint = "oss-cn-hangzhou.aliyuncs.com";
            //云账号AccessKey所有API访问权限 建议遵循阿里云安全最佳实践创建并适用 RAM子账号进行API访问或日常运维
            String accessKeyId = "LTAI5t7r1Aw5ndBsVy55R46m";
            String accessKeySecret = "ZjZEnr5QVeCrrZ2vstdEKm4y5Xdd21";
    
            //创建OSSClient实例
            OSS ossClient = new OSSClientBuilder().build(endPoint,accessKeyId,accessKeySecret);
            //文件流上传
    
            InputStream inputStream = new FileInputStream("C:\\Users\\Administrator.DESKTOP-UJHR16T\\Pictures\\I\\IMG_4909(20210220-081040).JPG");
            ossClient.putObject("gulimall-hello-11","Ha.JPG",inputStream);
            System.out.println("上传完成!");
            //oss客户端关闭
            ossClient.shutdown();
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    2.3 运行结果

    在这里插入图片描述

    2.4 查看bucket

    在这里插入图片描述

    三、使用阿里云sdk步骤

    3.1 导入依赖

    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alicloud-oss</artifactId>
        <version>2.2.0.RELEASE</version>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3.2 配置信息

    spring:
      cloud:
        alicloud:
          access-key: LTAI5t7r1Aw5ndBsVy55R4hhh
          secret-key: ZjZEnr5QVeCrrZ2vstdEKm4y5Xdsa
          oss:
            endPoint: oss-cn-hangzhou.aliyuncs.com
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3.3 编写代码

        @Autowired
         private OSSClient ossClient;
    
        @Test
        public void testUpload() throws FileNotFoundException {
           //文件流上传
           InputStream inputStream = new FileInputStream("C:\\Users\\Administrator.DESKTOP-UJHR16T\\Pictures\\Camera Roll\\IMG_6254.JPG");
           ossClient.putObject("gulimall-hello-1128","shuai.JPG",inputStream);
           System.out.println("上传完成!");
           //oss客户端关闭
           ossClient.shutdown();
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3.4 运行结果

    在这里插入图片描述

    3.5 查看bucket

    在这里插入图片描述

    四、OSS作为第三方服务

    4.1 创建 gulimall-third-party 微服务

    gulimall-third-party 第三方服务作为整个项目文件上传服务,若为每个微服务创建文件存储功能,都使用OSS对象存储服务则过于繁琐,只需创建gulimall-third-party 第三方服务即可。

    4.1.1 导入依赖

    <!--springcloud-alibababa的oss依赖-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alicloud-oss</artifactId>
        <version>2.2.0.RELEASE</version>
    </dependency>
    <!--web依赖-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--openfeign依赖-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    4.1.2 编写配置

    spring:
      cloud:
        nacos:
          discovery:
            server-addr: 127.0.0.1:8848
    
        alicloud:
          access-key: LTAI5t7r1Aw5ndBsVy55R4dsa
          secret-key: ZjZEnr5QVeCrrZ2vstdEKm4y5Xdas1
          oss:
            endPoint: oss-cn-hangzhou.aliyuncs.com
            bucket: gulimall-hello-1128
    
      application:
        name: gulimall-third-party
    server:
      port: 30000
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    spring.application.name=gulimall-third-party
    spring.cloud.nacos.config.server-addr=127.0.0.1:8848
    spring.cloud.nacos.config.namespace=1d48db76-7f24-4cd2-b671-8a0ee2esda1
    
    spring.cloud.nacos.config.ext-config[0].data-id=oss.yml
    spring.cloud.nacos.config.ext-config[0].group=DEFAULT_GROUP
    spring.cloud.nacos.config.ext-config[0].refresh=true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    4.1.3 编写代码

    @RestController
    public class OssController {
    
        @Autowired
        OSS ossClient;
    
        @Value("${spring.cloud.alicloud.oss.endpoint}")
        private String endpoint;
        @Value("${spring.cloud.alicloud.oss.bucket}")
        private String bucket;
        @Value("${spring.cloud.alicloud.access-key}")
        private String accessId;
    
    
        @RequestMapping("/oss/policy")
        public R policy() {
    
            //https://gulimall-hello-1128.oss-cn-hangzhou.aliyuncs.com/hahaha.jpg
    
            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 + "/"; // 用户上传文件时指定的前缀。
    
            Map<String, String> respMap = null;
            try {
                long expireTime = 30;
                long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
                Date expiration = new Date(expireEndTime);
                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(StandardCharsets.UTF_8);
                String encodedPolicy = BinaryUtil.toBase64String(binaryData);
                String postSignature = ossClient.calculatePostSignature(postPolicy);
    
                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));
                // respMap.put("expire", formatISO8601Date(expiration));
    
            } catch (Exception e) {
                // Assert.fail(e.getMessage());
                System.out.println(e.getMessage());
            }
    
            return R.ok().put("data",respMap);
        }
    }
    
    • 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
  • 相关阅读:
    使用SpringBoot快速构建Web API
    硕士论文章节划分
    2023.11.17-hive调优的常见方式
    vue+element el-input使用clearable后出现两个关闭图标
    使用CURAND在GPU和CPU上生成随机数的示例
    .NET 6 支持Cookie与JWT混合认证、授权的方法
    矩阵论理论知识(三)特殊的线性空间
    Json用法总结
    java计算机毕业设计网上扶贫农产品销售系统源码+系统+数据库+lw文档+mybatis+运行部署
    11.16 - 每日一题 - 408
  • 原文地址:https://blog.csdn.net/m0_49692893/article/details/125609481