spring boot使用阿里oss

Published on in 程序人生 with 0 views and 0 comments

1、引入pom

<dependency>
	<groupId>com.alibaba.cloud</groupId>
	<artifactId>aliyun-oss-spring-boot-starter</artifactId>
	<version>${alioss.version}</version>
</dependency>
<dependency>
	<groupId>com.aliyun.oss</groupId>
	<artifactId>aliyun-sdk-oss</artifactId>
	<version>${sdk.oss.version}</version>
</dependency>
<alioss.version>1.0.0</alioss.version>
<sdk.oss.version>3.15.1</sdk.oss.version>

2、yml配置

alibaba:
  cloud:
    accessKey: LTAI4GGgDAS4qGD2cajyz3Pr
    secretKey: cJ4EsHWwy7FLLIAuVRKbVJQZEoJQ9a
    oss: 
      endpoint: oss-cn-chengdu.aliyuncs.com
      bucketName: long-mall

3、上传文件

OSS支持多种文件上传方式,我选择服务端签名后直传,后端返回一个签名给前端,前端带着这个签名,直接将文件上传至OSS,这样可以降低服务端压力,可以参考服务端签名后直传 (aliyun.com)

以下是我的后端代码:

host属性规则为http://+bucketName+"."+endpoint

dir就是文件上传至OSS时存储的目录,我按照日期生成目录,这样的话,在oss中存储的目录就会每天按照日期新建一个目录

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 com.mall.thirdparty.utils.R;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;

@RefreshScope
@RestController
@RequestMapping("/third-party/oss")
public class OssController {
    @Resource
    private OSS ossClient;

    @Value("${alibaba.cloud.oss.bucketName}")
    private String bucketName;
    @Value("${alibaba.cloud.oss.endpoint}")
    private String endpoint;
    @Value("${alibaba.cloud.accessKey}")
    private String accessId;

    @GetMapping("/getPolicy")
    public R getPolicy(){
        try {
            String host = "https://"+bucketName+"."+endpoint;
            String dir = new SimpleDateFormat("yyyy-MM-dd").format(new Date())+"/";
            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);

            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 R.ok().put("ossData",respMap);

        }catch (Exception e){
            e.printStackTrace();
        }
        return R.error(500,"获取oss签名异常");
    }
}

前端vue代码如下,代码中使用了element-ui的组件,请求部分替换为自己的,需要注意action字段,组成规则为http://+bucketName+"."+endpoint

<template>
  <div>
    <el-upload
      action="http://long-mall.oss-cn-chengdu.aliyuncs.com"
      :data="dataObj"
      list-type="picture"
      :multiple="false"
      :show-file-list="showFileList"
      :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 './policy'
import { getUUID } from '@/utils'
export default {
  name: 'singleUpload',
  props: {
    value: String
  },
  computed: {
    imageUrl () {
      console.log(this.value)
      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 => {
          _self.dataObj.policy = response.ossData.policy
          _self.dataObj.signature = response.ossData.signature
          _self.dataObj.ossaccessKeyId = response.ossData.accessId
          _self.dataObj.key = response.ossData.dir + getUUID() + file.name
          _self.dataObj.dir = response.ossData.dir
          _self.dataObj.host = response.ossData.host
          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})
      this.emitInput(this.fileList[0].url)
    }
  }
}
</script>
<style>

</style>



4、yml中配置oss参数

alibaba:
  cloud:
    accessKey: 自己的accessKey
    secretKey: 自己的secretKey
    oss: 
      endpoint: oss-cn-chengdu.aliyuncs.com
      bucketName: 自己创建的bucketName

accessKey和secretKey可以在这里查看

image.png

bucketName就是自己配置的bucket的名称

endpoint根据自己的OSS配置的区域选择对应的外网Endpoint即可,地域和endpoint对照参考访问域名和数据中心 (aliyun.com)

自己的区域在这里可以看到

image.png

5、oss跨域配置

image.png

image.png


标题:spring boot使用阿里oss
作者:wenyl
地址:http://www.wenyoulong.com/articles/2023/05/30/1685444836877.html