1. 程式人生 > 程式設計 >SpringBoot整合阿里雲OSS物件儲存服務的實現

SpringBoot整合阿里雲OSS物件儲存服務的實現

今天來整合一下SpringBoot和阿里雲OSS物件儲存服務。

一、配置OSS服務

先在阿里雲開通物件儲存服務,拿到AccessKeyId、AccessKeySecret。

SpringBoot整合阿里雲OSS物件儲存服務的實現

建立你的bucket(儲存空間),相當於一個一個的資料夾目錄。按業務需求分類儲存你的檔案,圖片,音訊,app包等等。建立bucket是要選擇該bucket的許可權,私有,公共讀,公共讀寫,按需求選擇。建立bucket時對應的endpoint要記住,上傳檔案需要用到。

SpringBoot整合阿里雲OSS物件儲存服務的實現

可以配置bucket的生命週期,比如說某些檔案有過期時間的,可以配置一下。

SpringBoot整合阿里雲OSS物件儲存服務的實現

二、程式碼實現

引入依賴包

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

配置檔案application.yml

aliyun-oss:
 #bucket名稱
 bucketApp: xxx-app
 domainApp: https://xxx-app.oss-cn-shenzhen.aliyuncs.com/
 region: oss-cn-shenzhen
 endpoint : https://oss-cn-shenzhen.aliyuncs.com
 accessKeyId: 你的accessKeyId
 accessKeySecret: 你的accessKeySecret

對應上面配置檔案的properties類

package com.example.file.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "aliyun-oss")
@Data
public class AliyunOSSProperties {

  /**
   * 伺服器地點
   */
  private String region;
  /**
   * 伺服器地址
   */
  private String endpoint;
  /**
   * OSS身份id
   */
  private String accessKeyId;
  /**
   * 身份金鑰
   */
  private String accessKeySecret;

  /**
   * App檔案bucketName
   */
  private String bucketApp;
  /**
   * App包檔案地址字首
   */
  private String domainApp;
}

上傳檔案工具類

package com.example.file.utils;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;
import com.example.common.exception.BusinessErrorCode;
import com.example.common.exception.BusinessException;
import com.example.common.utils.FileIdUtils;
import com.example.file.config.AliyunOSSProperties;
import com.example.file.config.FileTypeEnum;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

@Component
public class AliyunOSSUtil {

  @Autowired
  private AliyunOSSProperties aliyunOSSProperties;

  private static Logger logger = LoggerFactory.getLogger(AliyunOSSUtil.class);

  /**
   * 檔案不存在
   */
  private final String NO_SUCH_KEY = "NoSuchKey";
  /**
   * 儲存空間不存在
   */
  private final String NO_SUCH_BUCKET = "NoSuchBucket";

  /**
   * 上傳檔案到阿里雲 OSS 伺服器
   *
   * @param files
   * @param fileTypeEnum
   * @param bucketName
   * @param storagePath
   * @return
   */
  public List<String> uploadFile(MultipartFile[] files,FileTypeEnum fileTypeEnum,String bucketName,String storagePath,String prefix) {
    //建立OSSClient例項
    OSSClient ossClient = new OSSClient(aliyunOSSProperties.getEndpoint(),aliyunOSSProperties.getAccessKeyId(),aliyunOSSProperties.getAccessKeySecret());
    List<String> fileIds = new ArrayList<>();
    try {
      for (MultipartFile file : files) {
      		//建立一個唯一的檔名,類似於id,就是儲存在OSS伺服器上檔案的檔名(自定義檔名)
        String fileName = FileIdUtils.creater(fileTypeEnum.getCode());
        InputStream inputStream = file.getInputStream();
        ObjectMetadata objectMetadata = new ObjectMetadata();
        //設定資料流裡有多少個位元組可以讀取
        objectMetadata.setContentLength(inputStream.available());
        objectMetadata.setCacheControl("no-cache");
        objectMetadata.setHeader("Pragma","no-cache");
        objectMetadata.setContentType(file.getContentType());
        objectMetadata.setContentDisposition("inline;filename=" + fileName);
        fileName = StringUtils.isNotBlank(storagePath) ? storagePath + "/" + fileName : fileName;
        //上傳檔案
        PutObjectResult result = ossClient.putObject(bucketName,fileName,inputStream,objectMetadata);
        logger.info("Aliyun OSS AliyunOSSUtil.uploadFileToAliyunOSS,result:{}",result);
        fileIds.add(prefix + fileName);
      }
    } catch (IOException e) {
      logger.error("Aliyun OSS AliyunOSSUtil.uploadFileToAliyunOSS fail,reason:{}",e);
    } finally {
      ossClient.shutdown();
    }
    return fileIds;
  }

  /**
   * 刪除檔案
   *
   * @param fileName
   * @param bucketName
   */
  public void deleteFile(String fileName,String bucketName) {
    OSSClient ossClient = new OSSClient(aliyunOSSProperties.getEndpoint(),aliyunOSSProperties.getAccessKeySecret());
    ossClient.deleteObject(bucketName,fileName);
    shutdown(ossClient);
  }

  /**
   * 根據圖片全路徑刪除就圖片
   *
   * @param imgUrl   圖片全路徑
   * @param bucketName 儲存路徑
   */
  public void delImg(String imgUrl,String bucketName) {
    if (StringUtils.isBlank(imgUrl)) {
      return;
    }
    //問號
    int index = imgUrl.indexOf('?');
    if (index != -1) {
      imgUrl = imgUrl.substring(0,index);
    }
    int slashIndex = imgUrl.lastIndexOf('/');
    String fileId = imgUrl.substring(slashIndex + 1);
    OSSClient ossClient = new OSSClient(aliyunOSSProperties.getEndpoint(),fileId);
    shutdown(ossClient);
  }

  /**
   * 判斷檔案是否存在
   *
   * @param fileName  檔名稱
   * @param bucketName 檔案儲存空間名稱
   * @return true:存在,false:不存在
   */
  public boolean doesObjectExist(String fileName,String bucketName) {
    Validate.notEmpty(fileName,"fileName can be not empty");
    Validate.notEmpty(bucketName,"bucketName can be not empty");
    OSSClient ossClient = new OSSClient(aliyunOSSProperties.getEndpoint(),aliyunOSSProperties.getAccessKeySecret());
    try {
      boolean found = ossClient.doesObjectExist(bucketName,fileName);
      return found;
    } finally {
      shutdown(ossClient);
    }

  }

  /**
   * 複製檔案
   *
   * @param fileName       原始檔名稱
   * @param bucketName      源儲存空間名稱
   * @param destinationBucketName 目標儲存空間名稱
   * @param destinationObjectName 目標檔名稱
   */
  public void ossCopyObject(String fileName,String destinationBucketName,String destinationObjectName) {
    Validate.notEmpty(fileName,"bucketName can be not empty");
    Validate.notEmpty(destinationBucketName,"destinationBucketName can be not empty");
    Validate.notEmpty(destinationObjectName,"destinationObjectName can be not empty");
    OSSClient ossClient = new OSSClient(aliyunOSSProperties.getEndpoint(),aliyunOSSProperties.getAccessKeySecret());
    // 拷貝檔案。
    try {
      ossClient.copyObject(bucketName,destinationBucketName,destinationObjectName);
    } catch (OSSException oe) {
      logger.error("errorCode:{},Message:{},requestID:{}",oe.getErrorCode(),oe.getMessage(),oe.getRequestId());
      if (oe.getErrorCode().equals(NO_SUCH_KEY)) {
        throw new BusinessException(BusinessErrorCode.NO_SUCH_KEY);
      } else if (oe.getErrorCode().equals(NO_SUCH_BUCKET)) {
        throw new BusinessException(BusinessErrorCode.NO_SUCH_BUCKET);
      } else {
        throw new BusinessException(BusinessErrorCode.FAIL);
      }
    } finally {
      shutdown(ossClient);
    }
  }

  /**
   * 關閉oos
   *
   * @param ossClient ossClient
   */
  private void shutdown(OSSClient ossClient) {
    ossClient.shutdown();
  }
}

檔案型別列舉

package com.example.file.config;

public enum FileTypeEnum {

  IMG(1,"圖片"),AUDIO(2,"音訊"),VIDEO(3,"視訊"),APP(4,"App包"),OTHER(5,"其他");

  private Integer code;
  private String message;

  FileTypeEnum(Integer code,String message) {
    this.code = code;
    this.message = message;
  }

  public Integer getCode() {
    return code;
  }

  public String getMessage() {
    return message;
  }

}

呼叫工具類上傳檔案

@Override
  public List<String> uploadImg(MultipartFile[] files) {
    if (files == null) {
      throw new BusinessException(BusinessErrorCode.OPT_UPLOAD_FILE);
    }
    try {
      return aliyunOSSUtil.uploadFile(files,FileTypeEnum.IMG,aliyunOSSProperties.getBucketProduct(),null,aliyunOSSProperties.getDomainProduct());
    } catch (Exception e) {
      logger.error("uploadImg error e:{}",e);
      throw new BusinessException(BusinessErrorCode.UPLOAD_FAIL);
    }
  }

返回的List是檔案上傳之後檔案的檔名集合。
到此就整合完成了。可以登入OSS控制檯檢視對應的檔案。更多相關SpringBoot整合阿里雲OSS內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!