阿里oss对象存储

2019/10/19 对象存储

为了处理公司上传大文件的需求,学习如何使用阿里对象存储oss进行上传文件、断点续传等功能,基于阿里oss的javaSdk做了简单的封装。

常见操作方法介绍

常见的操作方法有前端将文件上传到后台,通过后台sdk直接将文件上传到对象存储,也可以直接通过前端web直传到阿里oss。

认证生成OSS对象用于上传文件

  private static String key = "*";
  private static String secret = "*";
  private static String endpoint = "http://oss-cn-beijing.aliyuncs.com";
  private static String bucketName = "bucket-bm";
  private static String httpsUrl = "http://bucket-bm.oss-cn-beijing.aliyuncs.com/";
  /**
   * 分片大小
   */
  private static long partSize = 20 * 1024 * 1024;

  static OSSClient ossClient = null;

  static {
    ossClient = new OSSClient(endpoint, key, secret);
  }

分片上传和断点续传

/**
   * 断点上传文件
   *
   * @param fileName 文件名称
   * @param file 文件
   */
  public static String uploadCheckPoint(String fileName, MultipartFile file, String recordPath,HttpSession session)
      throws Throwable {
//    ObjectMetadata data = new ObjectMetadata();
//    // 设置上传类型
//    data.setContentType("video/mpeg4");
    File f = null;
    try {
      f = File.createTempFile("tmp", null);
      file.transferTo(f);
      f.deleteOnExit();
    } catch (Exception e) {
      e.printStackTrace();
    }

    UploadFileRequest uploadFileRequest = new UploadFileRequest(bucketName, fileName);
    //指定本地上传的文件
    uploadFileRequest.setUploadFile(f.getAbsolutePath());
    // 设置并发数默认为1
    uploadFileRequest.setTaskNum(30);
    // 设置分片上传大小
    uploadFileRequest.setPartSize(partSize);
    // 开启断点续传
    uploadFileRequest.setEnableCheckpoint(true);
    // 设置记录断点续传记录文件记录位置 如果不配置默认为上传文件的文件夹中
    uploadFileRequest.setCheckpointFile(recordPath);
    //
//    uploadFileRequest.setObjectMetadata(data);
    // 上传成功之后的回调
//    uploadFileRequest.setCallback(new Callback());
    uploadFileRequest.setProgressListener(new PutObjectProgressListener(session));
    SetBucketLoggingRequest request = new SetBucketLoggingRequest(bucketName);
    request.setTargetBucket(null);
    request.setTargetPrefix(null);
    ossClient.setBucketLogging(request);
    UploadFileResult uploadFileResult = ossClient.uploadFile(uploadFileRequest);
    //关闭ossClient
    ossClient.shutdown();
    return httpsUrl + fileName;
  }

监听上传进度


/**
 * @author : tangping
 * @description :
 * @Date : 2018/8/17/017 10:48
 */
public class PutObjectProgressListener implements ProgressListener {

  private long bytesWritten = 0;
  private long totalBytes = -1;
  private boolean succeed = false;
  private HttpSession session;

  public PutObjectProgressListener(HttpSession session) {
    this.session = session;
  }

  @Override
  public void progressChanged(ProgressEvent progressEvent) {
    long bytes = progressEvent.getBytes();
    ProgressEventType eventType = progressEvent.getEventType();
    switch (eventType) {
      case TRANSFER_STARTED_EVENT:
        System.out.println("Start to upload......");
        break;
      case REQUEST_CONTENT_LENGTH_EVENT:
        this.totalBytes = bytes;
        System.out.println(this.totalBytes + " bytes in total will be uploaded to OSS");
        break;
      case REQUEST_BYTE_TRANSFER_EVENT:
        this.bytesWritten += bytes;
        if (this.totalBytes != -1) {
          int percent = (int) (this.bytesWritten * 100.0 / this.totalBytes);
          this.session.setAttribute("progress",percent);
          System.out.println(
              bytes + " bytes have been written at this time, upload progress: " + percent + "%("
                  + this.bytesWritten + "/" + this.totalBytes + ")");
        } else {
          System.out.println(
              bytes + " bytes have been written at this time, upload ratio: unknown" + "("
                  + this.bytesWritten + "/...)");
        }
        break;
      case TRANSFER_COMPLETED_EVENT:
        this.succeed = true;
        System.out.println(
            "Succeed to upload, " + this.bytesWritten + " bytes have been transferred in total");
        break;
      case TRANSFER_FAILED_EVENT:
        System.out
            .println("Failed to upload, " + this.bytesWritten + " bytes have been transferred");
        break;
      default:
        break;
    }


  }

  public boolean isSucceed() {
    return succeed;
  }
}

web直传方式封装

web直传方式引入js-sdk

const applyTokenDo = function (func, refreshSts) {
   refresh = true;
  if (refresh) {
      $.ajax({
        url:'../progress/getToken',
        data:{},
        async:false,
        success:function (data) {
          client = new OSS({
            region:data.region,
            accessKeyId: data.accessKeyId,
            accessKeySecret: data.accessKeySecret,
            bucket:data.bucket
          });
        }
      });
      console.log(OSS.version);
      return func(client);
  }
  return func();
}

分片上传文件

const uploadFile = function uploadFile(client) {
  if (!uploadFileClient || Object.keys(uploadFileClient).length === 0) {
    uploadFileClient = client;
  }

  document.getElementById("start_time").innerHTML ="开始时间:" + new Date().toLocaleString();
  var interval = setInterval(function () {
    document.getElementById("end_time").innerHTML ="结束时间:"+ new Date().toLocaleString();
  },1000);

  const file = document.getElementById('file').files[0];
  const key = document.getElementById('object-key-file').value.trim() || 'object';

  console.log(`${file.name} => ${key}`);
  const options = {
    progress,
    partSize: 20*1024 * 1024,
    parallel: 30,
    meta: {
      year: 2017,
      people: 'test',
    },
  };
  if (currentCheckpoint) {
    options.checkpoint = currentCheckpoint;
  }
  return uploadFileClient.multipartUpload(key, file, options).then((res) => {
    console.log('upload success: %j', res);
    wx.miniProgram.postMessage({ data:{success:true,url:res.res.requestUrls[0] }})
    currentCheckpoint = null;
    uploadFileClient = null;
    clearInterval(interval);
  }).catch((err) => {
    wx.miniProgram.postMessage({ data:{success:false }})
    clearInterval(interval);
    if (uploadFileClient && uploadFileClient.isCancel()) {
      console.log('stop-upload!');
    } else {
      console.error(err);
    }
  });
};

进度条展示

const progress = async function progress(p, checkpoint) {
  currentCheckpoint = checkpoint;
  const bar = document.getElementById('progress-bar');
  bar.style.width = `${Math.floor(p * 100)}%`;
  bar.innerHTML = `${Math.floor(p * 100)}%`;
}

web直传的方式,体验性能等比较好。

Search

    Table of Contents