OSS存儲工具類分享(阿里)

    最近在家辦公,居然寫的還沒什麼可寫的,這是個壞習慣。多次鼓動下,公司終於換上了阿里的OSS存儲。我這邊也提前做好準備,儘管還不知道apiKey,apiSecret。系統也剛好還沒有這樣的工具類,先寫着備用吧。廢話不多說,直接上碼。

package com.xiaotian.bus.util;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.Bucket;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;


/**
 * 阿里雲OSS存儲工具類
 * @author zwsky
 */
@Component
@Slf4j
public class OSSObjectTools {

    private static String BUCKET_NAME;
    private static String END_POINT;
    private static String ACCESS_KEY_ID;
    private static String ACCESS_KEY_SECRET;

    /**
     * Endpoint以杭州爲例,其它Region請按實際情況填寫。
     */
    @Value("${ali.oss.endpoint}")
    private String endpoint;
    @Value("${ali.oss.accessKeyId}")
    private String accessKeyId;
    @Value("${ali.oss.accessKeySecret}")
    private String accessKeySecret;
    @Value("${ali.oss.img.pass.bucketName}")
    private String bucketName;
    private static OSS ossclient=null;

    /**
     * 常量初始化
     */
    @PostConstruct
    public void init() {
        BUCKET_NAME = bucketName;
        END_POINT = endpoint;
        ACCESS_KEY_ID = accessKeyId;
        ACCESS_KEY_SECRET = accessKeySecret;
    }




    /**
     * 獲取OSS連接
     * @return
     */
    private static void getOSSClient() {
        if (ossclient == null){
            ossclient = new OSSClientBuilder().build(END_POINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
        }
    }



    /**
     * 創建存儲空間
     *
     * param ossClient OSS連接
     * param bucketName 存儲空間
     * return
     */
    public static String createBucketName(String bucketName) {
        //獲取OSS存儲client
        getOSSClient();
        // 存儲空間
        final String bucketNames = bucketName;
        if (!ossclient.doesBucketExist(bucketName)) {
            // 創建存儲空間
            Bucket bucket = ossclient.createBucket(bucketName);
            log.info("創建存儲空間成功");
            return bucket.getName();
        }
        return bucketNames;
    }
    /**
     * 刪除存儲空間buckName
     *
     * param ossClient oss對象
     * param bucketName 存儲空間
     */
    public static void deleteBucket(String bucketName) {
        //獲取OSS存儲client
        getOSSClient();
        ossclient.deleteBucket(bucketName);
        log.info("刪除" + bucketName + "Bucket成功");
    }

    /**
     * 創建模擬文件夾
     *
     * param ossClient oss連接
     * param bucketName 存儲空間
     * param folder 模擬文件夾名如"qj_nanjing/"
     * return 文件夾名
     */
    public static String createFolder(String bucketName, String folder) {
        //獲取OSS存儲client
        getOSSClient();
        // 文件夾名
        final String keySuffixWithSlash = folder;
        // 判斷文件夾是否存在,不存在則創建
        if (!ossclient.doesObjectExist(bucketName, keySuffixWithSlash)) {
            // 創建文件夾
            ossclient.putObject(bucketName, keySuffixWithSlash, new ByteArrayInputStream(new byte[0]));
            log.info("創建文件夾成功");
            // 得到文件夾名
            OSSObject object = ossclient.getObject(bucketName, keySuffixWithSlash);
            String fileDir = object.getKey();
            return fileDir;
        }
        return keySuffixWithSlash;
    }


    /**
     * 根據key刪除OSS服務器上的文件
     *
     * param ossClient oss連接
     * param bucketName 存儲空間
     * param folder 模擬文件夾名 如"qj_nanjing/"
     * param key Bucket下的文件的路徑名+文件名 如:"upload/cake.jpg"
     */
    public static void deleteFile(String bucketName, String folder, String key) {
        //獲取OSS存儲client
        getOSSClient();
        ossclient.deleteObject(bucketName, folder + key);
        log.info("刪除" + bucketName + "下的文件" + folder + key + "成功");
    }


    /**
     * 上傳圖片至OSS
     *
     * param ossClient oss連接
     * param file 上傳文件(文件全路徑如:D:\\image\\cake.jpg)
     * param bucketName 存儲空間
     * param storePath 模擬文件夾名 如"qj_nanjing/"
     * return String 返回的唯一MD5數字簽名
     */
    public static String uploadObjectOSS(String storePath, File file,InputStream is) {
        //獲取OSS存儲client
        getOSSClient();
        String resultStr = null;
        createFolder(BUCKET_NAME, storePath);
        try {
            // 文件名
            String fileName = file.getName();
            // 文件大小
            Long fileSize = file.length();
            // 創建上傳Object的Metadata
            ObjectMetadata metadata = new ObjectMetadata();
            // 上傳的文件的長度
            metadata.setContentLength(is.available());
            // 指定該Object被下載時的網頁的緩存行爲
            metadata.setCacheControl("no-cache");
            // 指定該Object下設置Header
            metadata.setHeader("Pragma", "no-cache");
            // 指定該Object被下載時的內容編碼格式
            metadata.setContentEncoding("utf-8");
            // 文件的MIME,定義文件的類型及網頁編碼,決定瀏覽器將以什麼形式、什麼編碼讀取文件。如果用戶沒有指定則根據Key或文件名的擴展名生成,
            // 如果沒有擴展名則填默認值application/octet-stream
            metadata.setContentType(getContentType(fileName));
            // 指定該Object被下載時的名稱(指示MINME用戶代理如何顯示附加的文件,打開或下載,及文件名稱)
            metadata.setContentDisposition("filename/filesize=" + fileName + "/" + fileSize + "Byte.");
            // 上傳文件 (上傳文件流的形式)
            PutObjectResult putResult = ossclient.putObject(BUCKET_NAME, storePath + fileName, is, metadata);
            // 解析結果
            resultStr = storePath + fileName;
            log.info("putResult.getETag():"+putResult.getETag());
        } catch (Exception e) {
            e.printStackTrace();
            log.error("上傳阿里雲OSS服務器異常." + e.getMessage(), e);
        }
        return resultStr;
    }

    /**
     * 上傳圖片至OSS
     *
     * param ossClient oss連接
     * param file 上傳文件(文件全路徑如:D:\\image\\cake.jpg)
     * param bucketName 存儲空間
     * param storePath 模擬文件夾名 如"qj_nanjing/"
     * return String 返回的唯一MD5數字簽名
     */
    public static String uploadObjectOSS(String storePath,String fileName, File file,InputStream is) {
        //獲取OSS存儲client
        getOSSClient();
        String resultStr = null;
        createFolder(BUCKET_NAME, storePath);
        try {
          /*  // 文件名
            String fileName = file.getName();*/
            // 文件大小
            Long fileSize = file.length();
            // 創建上傳Object的Metadata
            ObjectMetadata metadata = new ObjectMetadata();
            // 上傳的文件的長度
            metadata.setContentLength(is.available());
            // 指定該Object被下載時的網頁的緩存行爲
            metadata.setCacheControl("no-cache");
            // 指定該Object下設置Header
            metadata.setHeader("Pragma", "no-cache");
            // 指定該Object被下載時的內容編碼格式
            metadata.setContentEncoding("utf-8");
            // 文件的MIME,定義文件的類型及網頁編碼,決定瀏覽器將以什麼形式、什麼編碼讀取文件。如果用戶沒有指定則根據Key或文件名的擴展名生成,
            // 如果沒有擴展名則填默認值application/octet-stream
            metadata.setContentType(getContentType(fileName));
            // 指定該Object被下載時的名稱(指示MINME用戶代理如何顯示附加的文件,打開或下載,及文件名稱)
            metadata.setContentDisposition("filename/filesize=" + fileName + "/" + fileSize + "Byte.");
            // 上傳文件 (上傳文件流的形式)
            PutObjectResult putResult = ossclient.putObject(BUCKET_NAME, storePath + fileName, is, metadata);
            // 解析結果
            resultStr = storePath + fileName;
            log.info("putResult.getETag():"+putResult.getETag());
        } catch (Exception e) {
            e.printStackTrace();
            log.error("上傳阿里雲OSS服務器異常." + e.getMessage(), e);
        }
        return resultStr;
    }


    /**
     * 上傳圖片至OSS
     *
     * param ossClient oss連接
     * param file 上傳文件(文件全路徑如:D:\\image\\cake.jpg)
     * param bucketName 存儲空間
     * param storePath 模擬文件夾名 如"qj_nanjing/"
     * return String 返回的唯一MD5數字簽名
     */
    public static String uploadObjectOSS1(String storePath,String fileName,InputStream is) {
        //獲取OSS存儲client
        getOSSClient();
        String resultStr = null;
        createFolder(BUCKET_NAME, storePath);
        try {
          /*  // 文件名
            String fileName = file.getName();*/
            // 文件大小

            // 創建上傳Object的Metadata
            ObjectMetadata metadata = new ObjectMetadata();
            // 上傳的文件的長度
            metadata.setContentLength(is.available());
            // 指定該Object被下載時的網頁的緩存行爲
            metadata.setCacheControl("no-cache");
            // 指定該Object下設置Header
            metadata.setHeader("Pragma", "no-cache");
            // 指定該Object被下載時的內容編碼格式
            metadata.setContentEncoding("utf-8");
            // 文件的MIME,定義文件的類型及網頁編碼,決定瀏覽器將以什麼形式、什麼編碼讀取文件。如果用戶沒有指定則根據Key或文件名的擴展名生成,
            // 如果沒有擴展名則填默認值application/octet-stream
            metadata.setContentType(getContentType(fileName));
            // 指定該Object被下載時的名稱(指示MINME用戶代理如何顯示附加的文件,打開或下載,及文件名稱)
            // metadata.setContentDisposition("filename/filesize=" + fileName + "/" + fileSize + "Byte.");
            // 上傳文件 (上傳文件流的形式)
            PutObjectResult putResult = ossclient.putObject(BUCKET_NAME, storePath + fileName, is, metadata);
            // 解析結果
            resultStr = storePath + fileName;
            log.info("putResult.getETag():"+putResult.getETag());
        } catch (Exception e) {
            e.printStackTrace();
            log.error("上傳阿里雲OSS服務器異常." + e.getMessage(), e);
        }
        return resultStr;
    }


    /**
     * 通過文件名判斷並獲取OSS服務文件上傳時文件的contentType
     *
     * param fileName 文件名
     * return 文件的contentType
     */
    public static String getContentType(String fileName) {

        // 文件的後綴名
        String fileExtension = fileName.substring(fileName.lastIndexOf("."));
        if (".bmp".equalsIgnoreCase(fileExtension)) {
            return "image/bmp";
        }
        if (".gif".equalsIgnoreCase(fileExtension)) {
            return "image/gif";
        }
        if (".jpeg".equalsIgnoreCase(fileExtension) || ".jpg".equalsIgnoreCase(fileExtension)
                || ".png".equalsIgnoreCase(fileExtension)) {
            return "image/jpeg";
        }
        if (".png".equalsIgnoreCase(fileExtension)) {
            return "image/png";
        }
        if (".html".equalsIgnoreCase(fileExtension)) {
            return "text/html";
        }
        if (".txt".equalsIgnoreCase(fileExtension)) {
            return "text/plain";
        }
        if (".vsd".equalsIgnoreCase(fileExtension)) {
            return "application/vnd.visio";
        }
        if (".ppt".equalsIgnoreCase(fileExtension) || "pptx".equalsIgnoreCase(fileExtension)) {
            return "application/vnd.ms-powerpoint";
        }
        if (".doc".equalsIgnoreCase(fileExtension) || "docx".equalsIgnoreCase(fileExtension)) {
            return "application/msword";
        }
        if (".xml".equalsIgnoreCase(fileExtension)) {
            return "text/xml";
        }
        // 默認返回類型
        return null;
    }


    @Test
    public void testAddUploadFileInfo() throws Exception{
        File file =new File("F:\\imag\\297913.jpg");
        FileInputStream fis = new FileInputStream(file);
        uploadObjectOSS("zbq/ces/", file,fis);
    }
}

實際上也沒什麼稀奇,之前阿里的OSS存儲SDK還是2.x版本就用過了。大家可能知道的,我不喜歡用舊碼的,所以順手改成最新的,實際上我這也是參考了其他博友的代碼。然後改成可以在配置文件配置相關信息的,這裏窮哦覺得其實還可以將BUCKET_NAME模擬文件夾、END_POINT節點配置抽到項目的業務表配置做,如果公司多個項目都用這個,業務模塊的存儲要分開,那肯定這樣處理更好。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章