OSS 文件存储服务器的学习

Updated on with 0 views and 0 comments

OSS 文件存储服务器的学习

OSS 文件存储服务器

OSS 文件存储服务器介绍

https://www.aliyun.com/product/oss/

开通对象存储 OSS

image-20210830223924723

点击创建Bucket按钮,弹出创建Bucket界面

特别强调这里的读写权限一定设置为“公共的”。 北京地域、低频段存储

image-20210830224529629

一般 访问外网 记录外网访问

Endpoint(地域节点)Bucket 域名
外网访问(IPv4)oss-cn-beijing.aliyuncs.comhb20210830.oss-cn-beijing.aliyuncs.com
外网访问(IPv4/IPv6)cn-beijing.oss.aliyuncs.comhb20210830.cn-beijing.oss.aliyuncs.com
ECS 的经典网络访问(内网)oss-cn-beijing-internal.aliyuncs.comhb20210830.oss-cn-beijing-internal.aliyuncs.com
ECS 的 VPC 网络访问(内网)oss-cn-beijing-internal.aliyuncs.comhb20210830.oss-cn-beijing-internal.aliyuncs.com

新建目录

image-20210830225216758

看懂说明文档 并 使用 https://help.aliyun.com/document_detail/51374.html?spm=5176.8465980.help.dexternal.41231450VMpKHN

查看目录 : 首页>对象存储 OSS>SDK 示例>Java

Maven 依赖(Java 9的话需更多)

<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>3.10.2</version>
</dependency>

image-20210830225754832

image-20210830225857458

点击: 开始使用子用户AccessKey

出现创建用户界面:输入登录用户名、显示用户名,勾选 编程访问,点击 确定即可创建用户。

image-20210830230109468

若开通 Open API 调用访问,请及时保存 AccessKey 信息,页面关闭后将无法再次获取信息。

用户登录名称AccessKey IDAccessKey Secret
0830_oos@1317924081557851.onaliyun.comLTAI5tMoynAfAcojTgfU3fnFPhzExMk0VrD7HeA8bzsz7lNkdmLoFG

添加权限

image-20210830230626335

上传文件流 Demo

public class OssDemo {
    public static void main(String[] args) throws FileNotFoundException {
        // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
        String endpoint = "oss-cn-beijing.aliyuncs.com";
        // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
        String accessKeyId = "LTAI5tMoynAfAcojTgfU3fnF";
        String accessKeySecret = "PhzExMk0VrD7HeA8bzsz7lNkdmLoFG";

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

        // 填写本地文件的完整路径。如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件流。
        InputStream inputStream = new FileInputStream("C:\\Users\\Administrator\\Desktop\\upload\\mimiup.png");
        // 依次填写Bucket名称(例如examplebucket)和Object完整路径(例如exampledir/exampleobject.txt)。Object完整路径中不能包含Bucket名称。
        ossClient.putObject("hb20210830", "pic/mimiup.png", inputStream);

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

上传的图片地址:https://hb20210830.oss-cn-beijing.aliyuncs.com/pic/mimiup.png bucket名.地域节点/文件目录

对比Bucket 域名:hb20210830.oss-cn-beijing.aliyuncs.com

文件通过服务器上传

每个 OSS 的用户都会用到上传服务。Web 端常见的上传方法是用户在浏览器或 APP 端上传文件到应用服务器,应用服务器再把文件上传到 OSS。具体流程如下图所示。

image-20210830232807189

和数据直传到 OSS 相比,以上方法有三个缺点:

上传慢:用户数据需先上传到应用服务器,之后再上传到OSS。网络传输时间比直传到OSS多一倍。如果用户数据不通过应用服务器中转,而是直传到OSS,速度将大大提升。而且OSS采用BGP带宽,能保证各地各运营商之间的传输速度。
扩展性差:如果后续用户多了,应用服务器会成为瓶颈。
费用高:需要准备多台应用服务器。由于OSS上传流量是免费的,如果数据直传到OSS,不通过应用服务器,可以节省应用服务器

创建模块 u-oss

添加依赖

    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- nacos 客户端-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <!-- OSS 存储-->
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>3.10.2</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <!-- SpringCloud的依赖 -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <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>

添加 Controller

@RestController
@RequestMapping("/oss")
public class UploadFileController {

    @PostMapping("/upload")
    public Map<String,String> upload(MultipartFile file) {
        // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
        String endpoint = "oss-cn-beijing.aliyuncs.com";
        // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
        String accessKeyId = "LTAI5tMoynAfAcojTgfU3fnF";
        String accessKeySecret = "PhzExMk0VrD7HeA8bzsz7lNkdmLoFG";
        String baseUrl = "https://hb20210830.oss-cn-beijing.aliyuncs.com/";

        String originalFilename = file.getOriginalFilename();
        String ext = StringUtils.getFilenameExtension(originalFilename);

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

        // 填写本地文件的完整路径。如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件流。
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 依次填写Bucket名称(例如examplebucket)和Object完整路径(例如exampledir/exampleobject.txt)。Object完整路径中不能包含Bucket名称。
        String uri = "pic/"+new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())+"."+ext;
        ossClient.putObject("hb20210830",uri , inputStream);

        System.out.println("文件访问路径"+baseUrl+uri);

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

        HashMap<String, String> map = new HashMap<>();

        map.put("url",baseUrl+uri);

        return map;
    }
}

配置文件

server:
  port: 10004
spring:
  application:
    name: oss
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.159.130:8848

通过 policy 上传 oss

因为通过服务器上传 需要先到达服务器 时间长了一倍 但是直接上传 oss 也不可取 因为会暴露自己的密码参数

服务器端获取签名,客户端直接上传到oss原理

image-20210831001755588

服务端签名后直传的原理如下:

  1. 用户发送上传Policy请求到应用服务器。
  2. 应用服务器返回上传Policy和签名给用户。
  3. 用户直接上传数据到OSS。

image-20210831001831141

参考官方文档:https://help.aliyun.com/document_detail/31926.htm

添加依赖 spring cloud 和 oss 整合包

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alicloud-oss</artifactId>
</dependency>

配置文件

server:
  port: 10004
spring:
  application:
    name: oss
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.159.130:8848
    alicloud:
      access-key: LTAI5tMoynAfAcojTgfU3fnF
      secret-key: PhzExMk0VrD7HeA8bzsz7lNkdmLoFG
      oss:
        endpoint: oss-cn-beijing.aliyuncs.com
        bucket: hb20210830

logging:
  level:
    com.offcn.oss: debug

写 新的 Controller UpdateByPolicyController

@RestController
@RequestMapping("/oss")
public class UpdateByPolicyController {

    @Autowired
    private OSS ossClient;

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

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

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

    @RequestMapping("/getPolicy")
    public Map<String, String> upload() {
        String host = "https://" + bucket + "." + endpoint; // host的格式为 bucketname.endpoint
        String formatDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        String dir = formatDate + "/"; // 用户上传文件时指定的前缀。
        Map<String, String> respMap = new LinkedHashMap<String, String>();
        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("utf-8");
            String encodedPolicy = BinaryUtil.toBase64String(binaryData);
            String postSignature = ossClient.calculatePostSignature(postPolicy);

            //封装accessid、签名等信息返回
            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));


        } catch (Exception e) {
            // Assert.fail(e.getMessage());
            System.out.println(e.getMessage());
        } finally {
            ossClient.shutdown();
        }

        return respMap;
    }
}

启动服务,访问controller获取签名

访问地址:http://localhost:10003/oss/getPolicy

image-20210831003730503

在前端工程renren-fast-vue目录src/utils/ 新建获取签名js文件 policy.js

import http from '@/utils/httpRequest.js'
export function policy () {
  return new Promise((resolve) => {
    http({
      url: http.adornUrl('/oss/getPolicy'),
      method: 'get',
      params: http.adornParams({})
    }).then(({ data }) => {
      resolve(data)
    })
  })
}

配置网关

- id: oss-route
  uri: lb://oss
  predicates:
    - Path=/api/renren-fast/oss/**
  filters:
    - StripPrefix=2

image-20210831005336596

在前端工程renren-fast-vue目录src/views/modules/common目录下 创建上传页面 singleUpload.vue

注意:**修改下面 action属性 ** 指向oss存储桶地址:http://java0817-001.oss-cn-guangzhou.aliyuncs.com!

<template> 
  <div>
    <el-upload
      action="https://hb20210830.oss-cn-beijing.aliyuncs.com"
      :data="dataObj"
      list-type="picture"
      :multiple="false" :show-file-list="showFileList"
      :auto-upload="true"
      :file-list="fileList"
      :before-upload="beforeUpload"
      :on-remove="handleRemove"
      :on-success="handleUploadSuccess"
      :on-preview="handlePreview">
      <el-button size="small" type="primary">点击上传</el-button>
      <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过10MB</div>
    </el-upload>
    <el-dialog :visible.sync="dialogVisible">
      <img width="100%" :src="fileList[0].url" alt="">
    </el-dialog>
  </div>
</template>
<script>
  import { policy } from '@/utils/policy'
  import { getUUID } from '@/utils'

  export default {
    name: 'singleUpload',
    props: {
      value: String
    },
    computed: {
      imageUrl () {
        return this.value
      },
      imageName () {
        if (this.value != null && this.value !== '') {
          return this.value.substr(this.value.lastIndexOf('/') + 1)
        } else {
          return null
        }
      },
      fileList () {
        return [{
          name: this.imageName,
          url: this.imageUrl
        }]
      },
      showFileList: {
        get: function () {
          return this.value !== null && this.value !== '' && this.value !== undefined
        },
        set: function (newValue) {
        }
      }
    },
    data () {
      return {
        dataObj: {
          policy: '',
          signature: '',
          key: '',
          ossaccessKeyId: '',
          dir: '',
          host: ''
          // callback:'',
        },
        dialogVisible: false
      }
    },
    methods: {
      emitInput (val) {
        this.$emit('input', val)
      },
      handleRemove (file, fileList) {
        this.emitInput('')
      },
      handlePreview (file) {
        this.dialogVisible = true
      },
      beforeUpload (file) {
        let _self = this
        return new Promise((resolve, reject) => {
          policy().then(response => {
            console.log(response)
            _self.dataObj.policy = response.policy
            _self.dataObj.signature = response.signature
            _self.dataObj.ossaccessKeyId = response.accessid
            _self.dataObj.key = response.dir + getUUID() + file.name
            _self.dataObj.dir = response.dir
            _self.dataObj.host = response.host
            // console.log(_self.dataObj)
            resolve(true)
          })
        })
      },
      handleUploadSuccess (res, file) {
        console.log('上传成功...')
        this.showFileList = true
        this.fileList.pop()
        this.fileList.push({ name: file.name, url: this.dataObj.host + '/' + this.dataObj.key })
        console.log(this.dataObj.host + '/' + this.dataObj.key)
        this.emitInput(this.fileList[0].url)
      }
    }
  }
</script>
<style>

</style>

在前端工程renren-fast-vue目录src/views/modules/question目录下 修改页面 type-add-or-update.vue

引入上传控件

import SingleUpload from '../../common/singleUpload' // 引入单文件上传组件

注册上传组件:

export default {
    components:{ SingleUpload }
  }

修改分类logo输入框,改成上传按钮

<el-form-item label="类型logo路径" prop="logoUrl">
     <single-upload v-model="dataForm.logoUrl"></single-upload>
    </el-form-item>

不成功image-20210831013255127

必须去设置 权限控制 跨域设置

image-20210831013351062


标题:OSS 文件存储服务器的学习
作者:HB2Ocean
地址:http://future-hb.top:8080/articles/2021/09/05/1630826861158.html