阿里雲OSS Java工具類

阿里雲OSS Java工具類

阿里雲對象存儲服務(Object Storage Service,簡稱 OSS),是阿里雲提供的海量、安全、低成本、高可靠的雲存儲服務。其數據設計持久性不低於 99.9999999999%(12 個 9),服務設計可用性(或業務連續性)不低於 99.995%。
OSS 具備與平臺無關的 RESTful API 接口,您能夠在任何應用、任什麼時候間、任何地點存儲和訪問任意類型的數據。
您可使用阿里雲提供的 API、SDK 接口或者 OSS 遷移工具輕鬆地將海量數據移入或移出阿里雲 OSS。數據存儲到阿里雲 OSS 之後,您能夠選擇標準存儲(Standard)做爲移動應用、大型網站、圖片分享或熱點音視頻的主要存儲方式,也能夠選擇成本更低、存儲期限更長的低頻訪問存儲(Infrequent Access)和歸檔存儲(Archive)做爲不常常訪問數據的存儲方式。html

以上內容引用自阿里雲官網前端

價格

目前阿里雲OSS的價格是40GB/年9元,若是你是白嫖用戶,那麼請轉向七牛。java

你覺得購買了40G/年的容量就不用付費了嗎?那你就錯了,這只是存儲費用,使用OSS還須要支付流量費用。可是流量費用是單獨計算的。web

  • 存儲價格 0.148 元 /GB/月
  • 流量價格 忙時 0.50 元 /GB
  • 請求費用 0.01 元 /萬次
    上述的40G/年指的是存儲價格,並不包含流量和請求費用。
    具體內容可參見:計價表

OSS能夠作什麼?

它能夠搭建本身的牀圖(配合PicGO),備份網站,數據庫(配合寶塔)等。也能夠在開發過程當中充當文件服務器,阿里雲OSS宣稱99.9999999999%的可靠性,另外加上價格相對低廉,是做爲圖片/文件服務器的不二之選。spring

你要知道的一些概念

存儲空間(Bucket)

存儲空間是用戶用於存儲對象(Object)的容器,全部的對象都必須隸屬於某個存儲空間。存儲空間具備各類配置屬性,包括地域、訪問權限、存儲類型等。用戶能夠根據實際需求,建立不一樣類型的存儲空間來存儲不一樣的數據。數據庫

  • 同一個存儲空間的內部是扁平的,沒有文件系統的目錄等概念,全部的對象都直接隸屬於其對應的存儲空間。
  • 每一個用戶能夠擁有多個存儲空間。
  • 存儲空間的名稱在 OSS 範圍內必須是全局惟一的,一旦建立以後沒法修更名稱。
  • 存儲空間內部的對象數目沒有限制。

存儲空間的命名規範以下:apache

  • 只能包括小寫字母、數字和短橫線(-)。數組

  • 必須以小寫字母或者數字開頭和結尾。安全

  • 長度必須在 3–63 字節之間。springboot

對象/文件(Object)

對象是 OSS 存儲數據的基本單元,也被稱爲 OSS 的文件。對象由元信息(Object Meta),用戶數據(Data)和文件名(Key)組成。對象由存儲空間內部惟一的 Key 來標識。對象元信息是一組鍵值對,表示了對象的一些屬性,好比最後修改時間、大小等信息,同時用戶也能夠在元信息中存儲一些自定義的信息。

對象的生命週期是從上傳成功到被刪除爲止。在整個生命週期內,只有經過追加上傳的 Object 能夠繼續經過追加上傳寫入數據,其餘上傳方式上傳的 Object 內容沒法編輯,您能夠經過重複上傳同名的對象來覆蓋以前的對象。

對象的命名規範以下:

  • 使用 UTF-8 編碼。

  • 長度必須在 1–1023 字節之間。

  • 不能以正斜線(/)或者反斜線(\)開頭。

Endpoint(訪問域名)

Endpoint 表示 OSS 對外服務的訪問域名。OSS 以 HTTP RESTful API 的形式對外提供服務,當訪問不一樣的 Region 的時候,須要不一樣的域名。經過內網和外網訪問同一個 Region 所須要的 Endpoint 也是不一樣的。例如杭州 Region 的外網 Endpoint 是 oss-cn-hangzhou.aliyuncs.com,內網 Endpoint 是 oss-cn-hangzhou-internal.aliyuncs.com。

AccessKey(訪問密鑰)

AccessKey(簡稱 AK)指的是訪問身份驗證中用到的 AccessKeyId 和 AccessKeySecret。OSS 經過使用 AccessKeyId 和 AccessKeySecret 對稱加密的方法來驗證某個請求的發送者身份。AccessKeyId 用於標識用戶;AccessKeySecret 是用戶用於加密簽名字符串和 OSS 用來驗證簽名字符串的密鑰,必須保密。對於 OSS 來講,AccessKey 的來源有:

  • Bucket 的擁有者申請的 AccessKey。
  • 被 Bucket 的擁有者經過 RAM 受權給第三方請求者的 AccessKey。
  • 被 Bucket 的擁有者經過 STS 受權給第三方請求者的 AccessKey。

JAVA工具類-準備篇

這裏介紹一份基於java實現的阿里雲OSS工具類,代碼基於阿里雲官方OSS官方API文檔。此項目使用Maven搭建,須要使用幾個依賴。具體依賴以下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>cn.rayfoo</groupId>
    <artifactId>ALiOSS-demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <!-- maven-compiler-plugin 將會使用指定的 JDK 版本將 java 文件編譯爲 class 文件(針對編譯運行環境) -->
        <maven.compiler.target>1.8</maven.compiler.target>
        <!-- maven-compiler-plugin 將會使用指定的 JDK 版本對源代碼進行編譯(針對編譯運行環境) -->
        <maven.compiler.source>1.8</maven.compiler.source>
    </properties>


    <dependencies>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.1.5.RELEASE</version>
        </dependency>

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

</project>

此工具類須要調用resource下的aliyunOSS.properties文件,具體配置以下

AccessKey=yourAccessKey
AccessKeySecret=yourAccessKeySecret
Buckets=yourBuckets
EndPoint=https://oss-cn-beijing.aliyuncs.com

因爲此工具類又用到我封裝的另外一個工具類:PropertiesReader,因此在此處提供該工具類的代碼。

注意:

  • 這份工具類建議須要1.8及以上版本的JDK
package cn.rayfoo.util;

import java.io.InputStream;
import java.util.Properties;

/**
 * Created by rayfoo@qq.com Luna on 2020/4/15 18:38
 * Description : 讀取配置文件工具類
 */
public class PropertiesReader {

    //建立Properties對象
    private static Properties property = new Properties();

    //在靜態塊中加載資源
    static {
        //使用try(){}.. 獲取數據源
        //注意 * 這是jdk1.7開始支持的特性,若是使用的是低版本 須要提高jdk版本 或者更改寫法
        try (
                InputStream in = PropertiesReader.class.getResourceAsStream("/aliyunOSS.properties");
        ) {
            property.load(in);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 返回Properties對象
     * @return
     */
    public static Properties getProperties(){
        return property;
    }

    /**
     * 獲取字符串類型的值
     * @param key
     * @return
     */
    public static String get(String key) {
        return property.getProperty(key);
    }

    /**
     * 獲取Integer類型的值
     * @param key
     * @return
     */
    public static Integer getInteger(String key) {
        String value = get(key);
        return null == value ? null : Integer.valueOf(value);
    }

    /**
     * 獲取Boolean類型的值
     * @param key
     * @return
     */
    public static Boolean getBoolean(String key) {
        String value = get(key);
        return null == value ? null : Boolean.valueOf(value);
    }

    /**
     * 設置一個鍵值對
     * @param key
     * @param value
     */
    public static void set(String key,String value){
        property.setProperty(key,value);
    }

    /**
     * 添加一個鍵值對
     * @param key
     * @param value
     */
    public static void add(String key,Object value){
        property.put(key,value);
    }
}

工具類代碼

該工具類集成了OSS的上傳、下載等功能。

參數介紹

下面的代碼中會用到不少個參數名,咱們要先明白它們表明什麼

參數名 含義
oranName 表明用戶傳過來未經處理的文件名 例如/img/a.jpg
objectName 表明去掉前面/ 加上uuid後的文件名 如img/330ddd7feb6d456f8ee97092d7675c90a.jgp
realName 指的是存放在OSS中的全路徑

屬性介紹

屬性名 介紹
accessKeyId 這個屬性會從aliyunOSS.properties中讀取key爲AccessKey的內容
accessKeySecret 這個屬性會從aliyunOSS.properties中讀取key爲AccessKeySecret的內容
endpoint 這個屬性會從aliyunOSS.properties中讀取key爲Endpoint的內容
bucketName 這個屬性會從aliyunOSS.properties中讀取key爲BucketName的內容

方法介紹

方法名 介紹
getURLHead() 返回url頭信息,即https://+bucketName+endpoint
String getObjectName(String fileURL) 經過文件URL反向解析文件名
List getObjectNames(List fileURLs) 批量獲取 objectName
String getRealName(String oranName) 獲取存放在OSS中的全路徑
void printUploadSuccessInfo(String fileURL) 上傳成功後打印文件的存儲地址,測試方法
void printDeleteSuccessInfo(String fileURL) 刪除成功後打印文件的存儲地址,測試方法
String getRandomImageName(String oranName) 在oranName以前加入一個uuid並返回新的oranName
String createBucket(String bucket) 建立一個新的Bucket
String getBucketName(String fileURL) 根據url獲取bucketName
void useBucketName(String bucket) 切換到某個bucket
void useBucketNameByURL(String fileURL) 切換到url所在的bucket
String upLoadTextFile(String oranFileName, String content) 上傳一個文本文件到服務器上,獲取realName
String uploadBytesFile(String oranFileName, byte[] content) 上傳一個byte數組到服務器上,可用於web中的圖片提交,獲取realName
String uploadNetworkFlows(String oranFileName, String url) 上傳網絡流,獲取realName
String uploadFileInputSteam(String oranFileName, File file) 上傳文件流,獲取realName
String uploadLocalFile(String oranFileName, String localFileName) 上傳一個本地文件,獲取realName
void deleteFile(String fileURL) 刪除指定路徑下的一個文件
void deleteFile(List fileURL) 刪除指定路徑下的多個文件
boolean exists(String fileURL) 存在爲true,不存在爲false
void downloadFileToLoacal(String fileURL, String localFileName) 從OSS中下載一個文件到本地
StringBuffer downloadStream(String fileURL) 以流的方式讀取一個文件 並打印 返回讀取到的內容
Object getCloudPropertiesGetValue(String fileName, String key) 以流的方式讀取一個雲端properties文件的key對應的value 並打印

工具類代碼

package cn.rayfoo.util;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.*;

import java.io.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.UUID;

/**
 * Created by rayfoo@qq.com Luna on 2020/4/15 23:12
 * Description:阿里雲 OSS 文件上傳工具類
 * oranName : 表明用戶傳過來未經處理的文件名 例如/img/a.jpg
 * objectName : 表明去掉前面/ 加上uuid後的文件名 如img/330ddd7feb6d456f8ee97092d7675c90a.jgp
 * getRealName(objectName) : 指的是存放在OSS中的全路徑
 */
public class AliOSSUtil {

    //AccessKey
    private static String accessKeyId = null;
    //AccessKeySecret
    private static String accessKeySecret = null;
    //Endpoint
    private static String endpoint = null;
    //bucketName
    private static String bucketName = null;

    /**
     * 靜態塊
     */
    static {
        //初始化AccessKey
        accessKeyId = PropertiesReader.get("AccessKey");
        //初始化AccessKeySecret
        accessKeySecret = PropertiesReader.get("AccessKeySecret");
        //初始化Endpoint
        endpoint = PropertiesReader.get("EndPoint");
        //初始化bucketName
        bucketName = PropertiesReader.get("Buckets");
    }

    /**
     * 私有化構造
     */
    private AliOSSUtil() {

    }

    /**
     * 獲取圖片的URL頭信息
     *
     * @return 返回url頭信息
     */
    private static String getURLHead() {
        //從哪一個位置截取
        int cutPoint = endpoint.lastIndexOf('/') + 1;
        //http頭
        String head = endpoint.substring(0, cutPoint);
        //服務器地址信息
        String tail = endpoint.substring(cutPoint);
        //返回結果
        return head + bucketName + "." + tail + "/";
    }

    /**
     * 經過文件URL反向解析文件名
     *
     * @param fileURL 文件URL
     * @return 原文件名
     */
    private static String getObjectName(String fileURL) {
        return fileURL.substring(getURLHead().length());
    }

    /**
     * 批量獲取 objectName
     *
     * @param fileURLs url列表
     * @return objectName列表
     */
    private static List<String> getObjectNames(List<String> fileURLs) {
        //建立返回對象
        List<String> result = null;
        //迭代轉換
        for (String item : fileURLs) {
            result.add(item.substring(getURLHead().length()));
        }
        return result;
    }

    /**
     * 獲取存儲在服務器上的地址
     *
     * @param oranName 文件名
     * @return 文件URL
     */
    private static String getRealName(String oranName) {
        return getURLHead() + oranName;
    }

    /**
     * 打印文件的存儲地址
     *
     * @param fileURL 文件URL
     */
    private static void printUploadSuccessInfo(String fileURL) {
        //上傳成功
        System.out.println("upload success, path = " + getRealName(fileURL));
    }

    /**
     * 打印文件的存儲地址
     *
     * @param fileURL 文件URL
     */
    private static void printDeleteSuccessInfo(String fileURL) {
        //上傳成功
        System.out.println("delete success, path = " + getRealName(fileURL));
    }


    /**
     * 獲取一個隨機的文件名
     *
     * @param oranName 初始的文件名
     * @return 返回加uuid後的文件名
     */
    private static String getRandomImageName(String oranName) {
        //獲取一個uuid 去掉-
        String uuid = UUID.randomUUID().toString().replace("-", "");
        //查一下是否帶路徑
        int cutPoint = oranName.lastIndexOf("/") + 1;
        //若是存在路徑
        if (cutPoint != 0) {
            //掐頭 若是開頭是/ 則去掉
            String head = oranName.indexOf("/") == 0 ? oranName.substring(1, cutPoint) : oranName.substring(0, cutPoint);
            //去尾
            String tail = oranName.substring(cutPoint);
            //返回正確的帶路徑的圖片名稱
            return head + uuid + tail;
        }
        //不存在 直接返回
        return uuid + oranName;
    }

    /**
     * 建立一個Bucket,這個參數由參數傳入 並不是配置文件讀取
     *
     * @param bucket BucketName 此處參數名喂Bucket是爲了避免和buckName衝突
     */
    public static String createBucket(String bucket) {

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

        // 建立存儲空間。
        ossClient.createBucket(bucket);

        // 關閉OSSClient。
        ossClient.shutdown();

        return bucket;

    }


    /**
     * 根據url獲取bucketName
     *
     * @param fileURL 文件的URL
     * @return bucketName
     */
    public static String getBucketName(String fileURL) {
        //前綴
        String prefix = "http://";
        //後綴
        String suffix = ".";
        //截取起始位置
        int beginIndex = fileURL.indexOf(prefix);
        //截取結束位置
        int endIndex = fileURL.indexOf(suffix);
        //若是不是http
        if (beginIndex == -1) {
            prefix = "https://";
            beginIndex = fileURL.indexOf(prefix);
            //若是仍是-1 那就是沒找到 返回-1便可
            if (beginIndex == -1)
                return null;
        }
        //設置起始位置
        beginIndex = prefix.length();
        //返回bucketName
        return fileURL.substring(beginIndex, endIndex);
    }

    /**
     * 切換bucket
     *
     * @param bucket 新的bucket名稱
     */
    public static void useBucketName(String bucket) {
        bucketName = bucket;
        PropertiesReader.set("Buckets", bucket);
    }

    /**
     * 切換bucket
     *
     * @param fileURL 根據URL設置新的BucketName
     */
    public static void useBucketNameByURL(String fileURL) {
        PropertiesReader.set("Buckets", getBucketName(fileURL));
    }

    /**
     * 上傳一個文本文件到服務器上
     *
     * @param oranFileName 上傳到服務器上的文件路徑和名稱 文本文件通常以.txt爲後綴
     * @param content      上傳的內容
     */
    public static String upLoadTextFile(String oranFileName, String content) {

        // <yourObjectName>上傳文件到OSS時須要指定包含文件後綴在內的完整路徑,例如abc/efg/123.jpg
        String objectName = getRandomImageName(oranFileName);

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

        // 上傳內容到指定的存儲空間(bucketName)並保存爲指定的文件名稱(objectName)。
        ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content.getBytes()));

        //上傳成功 打印文件存儲地址
        printUploadSuccessInfo(objectName);

        // 關閉OSSClient。
        ossClient.shutdown();

        //返回文件在服務器上的全路徑+名稱
        return getRealName(objectName);
    }


    /**
     * 上傳一個byte數組到服務器上
     *
     * @param oranFileName 上傳到服務器上的文件路徑和名稱
     * @param content      上傳的內容
     */
    public static String uploadBytesFile(String oranFileName, byte[] content) {

        // <yourObjectName>上傳文件到OSS時須要指定包含文件後綴在內的完整路徑,例如abc/efg/123.jpg
        String objectName = getRandomImageName(oranFileName);

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

        // 上傳Byte數組。
        ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content));

        //上傳成功 打印文件存儲地址
        printUploadSuccessInfo(objectName);

        // 關閉OSSClient。
        ossClient.shutdown();

        //返回文件在服務器上的全路徑+名稱
        return getRealName(objectName);
    }

    /**
     * 上傳網絡流
     *
     * @param oranFileName 上傳到服務器上的文件路徑和名稱
     * @param url          網絡上文件的url
     */
    public static String uploadNetworkFlows(String oranFileName, String url) {

        // <yourObjectName>上傳文件到OSS時須要指定包含文件後綴在內的完整路徑,例如abc/efg/123.jpg
        String objectName = getRandomImageName(oranFileName);

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

        try (
                // 上傳網絡流。
                InputStream inputStream = new URL(url).openStream();) {

            //上傳到OSS
            ossClient.putObject(bucketName, objectName, inputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }

        //上傳成功 打印文件存儲地址
        printUploadSuccessInfo(objectName);

        // 關閉OSSClient。
        ossClient.shutdown();

        //返回文件在服務器上的全路徑+名稱
        return getRealName(objectName);
    }

    /**
     * 上傳文件流
     *
     * @param oranFileName 上傳到服務器上的文件路徑和名稱
     * @param file         來自本地的文件或者文件流
     */
    public static String uploadFileInputSteam(String oranFileName, File file) {

        // <yourObjectName>上傳文件到OSS時須要指定包含文件後綴在內的完整路徑,例如abc/efg/123.jpg
        String objectName = getRandomImageName(oranFileName);

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

        // 上傳文件流。
        try (InputStream inputStream = new FileInputStream(file);) {
            //上傳到OSS
            ossClient.putObject(bucketName, objectName, inputStream);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        //上傳成功 打印文件存儲地址
        printUploadSuccessInfo(objectName);

        // 關閉OSSClient。
        ossClient.shutdown();

        //返回文件在服務器上的全路徑+名稱
        return getRealName(objectName);
    }

    /**
     * 上傳一個本地文件
     *
     * @param oranFileName  上傳到服務器上的名稱和路徑
     * @param localFileName 須要提供路徑和文件名
     */
    public static String uploadLocalFile(String oranFileName, String localFileName) {

        // <yourObjectName>上傳文件到OSS時須要指定包含文件後綴在內的完整路徑,例如abc/efg/123.jpg
        String objectName = getRandomImageName(oranFileName);

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

        // 建立PutObjectRequest對象。
        PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, new File(localFileName));

        // 若是須要上傳時設置存儲類型與訪問權限,請參考如下示例代碼。
        // ObjectMetadata metadata = new ObjectMetadata();
        // metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
        // metadata.setObjectAcl(CannedAccessControlList.Private);
        // putObjectRequest.setMetadata(metadata);

        // 上傳文件。
        ossClient.putObject(putObjectRequest);

        //上傳成功 打印文件存儲地址
        printUploadSuccessInfo(objectName);

        // 關閉OSSClient。
        ossClient.shutdown();

        //返回文件在服務器上的全路徑+名稱
        return getRealName(objectName);
    }


    /**
     * 刪除指定路徑下的一個文件
     *
     * @param fileURL 文件的全稱
     */
    public static void deleteFile(String fileURL) {

        // 反向解析文件名
        String objectName = getObjectName(fileURL);

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

        // 刪除文件。如需刪除文件夾,請將ObjectName設置爲對應的文件夾名稱。若是文件夾非空,則須要將文件夾下的全部object刪除後才能刪除該文件夾。
        ossClient.deleteObject(bucketName, objectName);

        //刪除成功 打印文件存儲地址
        printDeleteSuccessInfo(fileURL);

        // 關閉OSSClient。
        ossClient.shutdown();
    }

    /**
     * 刪除指定路徑下的多個文件--該方法未測試
     *
     * @param fileURL 要刪除的多個文件的集合
     */
    public static void deleteFile(List<String> fileURL) {

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

        // 刪除文件。key等同於ObjectName,表示刪除OSS文件時須要指定包含文件後綴在內的完整路徑,例如abc/efg/123.jpg。
        List<String> keys = new ArrayList<>();
        //批量添加要刪除的元素
        for (String item : fileURL) {
            keys.add(getObjectName(item));
        }

        //刪除
        DeleteObjectsResult deleteObjectsResult = ossClient.deleteObjects(new DeleteObjectsRequest(bucketName).withKeys(keys));
        List<String> deletedObjects = deleteObjectsResult.getDeletedObjects();

        //批量添加要刪除的元素
        for (String item : fileURL) {
            printDeleteSuccessInfo(item);
        }

        // 關閉OSSClient。
        ossClient.shutdown();
    }

    /**
     * 經過文件的URL 判斷文件是否存在
     *
     * @param fileURL 文件的URL
     * @return 文件是否存在
     */
    public static boolean exists(String fileURL) {

        // 反向解析文件名
        String objectName = getObjectName(fileURL);

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

        // 判斷文件是否存在。doesObjectExist還有一個參數isOnlyInOSS,若是爲true則忽略302重定向或鏡像;若是爲false,則考慮302重定向或鏡像。
        boolean found = ossClient.doesObjectExist(bucketName, objectName);

        // 關閉OSSClient。
        ossClient.shutdown();

        //  返回是否存在
        return found;
    }

    /**
     * 從OSS中下載一個文件
     *
     * @param fileURL       文件的url
     * @param localFileName 下載到本地的文件名稱
     */
    public static void downloadFileToLoacal(String fileURL, String localFileName) {

        //將url解析成objectName
        String objectName = getObjectName(fileURL);

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

        // 下載OSS文件到本地文件。若是指定的本地文件存在會覆蓋,不存在則新建。
        ossClient.getObject(new GetObjectRequest(bucketName, objectName), new File(localFileName));

        // 關閉OSSClient。
        ossClient.shutdown();

    }


    /**
     * 以流的方式讀取一個文件 並打印
     *
     * @param fileURL 文件的url
     */
    public static StringBuffer downloadStream(String fileURL) {
        //<yourObjectName>表示從OSS下載文件時須要指定包含文件後綴在內的完整路徑,例如abc/efg/123.jpg。
        String objectName = getObjectName(fileURL);

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

        // ossObject包含文件所在的存儲空間名稱、文件名稱、文件元信息以及一個輸入流。
        OSSObject ossObject = ossClient.getObject(bucketName, objectName);

        // 讀取文件內容。
        System.out.println("Object content:");

        StringBuffer sb = new StringBuffer();
        //使用try(){}..關閉資源
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent()));) {
            //讀取
            while (true) {
                String line = reader.readLine();
                if (line == null) break;
                sb.append(line);
                System.out.println("\n" + line);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        // 關閉OSSClient。
        ossClient.shutdown();
        //返回讀取到的內容
        return sb;
    }

    /**
     * 以流的方式讀取一個雲端properties文件的key對應的value 並打印
     *
     * @param fileName 文件的url
     */
    public static Object getCloudPropertiesGetValue(String fileName, String key) {

        //properties 文件夾的前綴
        String prefix = "properties/";
        //properties 文件夾的後綴
        String suffix = ".properties";

        //<yourObjectName>表示從OSS下載文件時須要指定包含文件後綴在內的完整路徑,例如abc/efg/123.jpg。
        String objectName = prefix + fileName + suffix;

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

        // ossObject包含文件所在的存儲空間名稱、文件名稱、文件元信息以及一個輸入流。
        OSSObject ossObject = ossClient.getObject(bucketName, objectName);

        // 讀取文件內容。
        System.out.println("Object content:");

        //獲取一個Properties對象
        Properties properties = PropertiesReader.getProperties();

        try (
                //獲取文件流
                InputStream inputStream = ossObject.getObjectContent();) {
            properties.load(inputStream);
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        // 關閉OSSClient。
        ossClient.shutdown();
        //返回讀取到的內容
        return properties.get(key);
    }
}

適用於SpringBoot的簡化版工具類

Properties文件

aliyun.AccessKeyID=yourAccessKeyID
aliyun.AccessKeySecret=yourAccessKeySecret
aliyun.Buckets=yourBuckets
aliyun.EndPoint=https://oss-cn-beijing.aliyuncs.com
aliyun.prefix=prefix/

工具類代碼

package cn.rayfoo.utils;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;

/**
 * @Author: rayfoo@qq.com
 * @Date: 2020/7/13 3:11 下午
 * @Description:
 */
public class AliyunOSSUtils {

    /**
     * 阿里雲的配置參數
     */
    private static String accessKeyId = null;
    private static String accessKeySecret = null;
    private static String endpoint = null;
    private static String bucketName = null;
    /**
     * 存儲在OSS中的前綴名
     */
    private static  String file_prefix = null;


    /**
     * 靜態塊
     */
    static {
        //初始化AccessKey
        accessKeyId = PropertiesReader.get("aliyun.AccessKeyID");
        //初始化AccessKeySecret
        accessKeySecret = PropertiesReader.get("aliyun.AccessKeySecret");
        //初始化Endpoint
        endpoint = PropertiesReader.get("aliyun.EndPoint");
        //初始化bucketName
        bucketName = PropertiesReader.get("aliyun.Buckets");
        //初始化前綴
        file_prefix = PropertiesReader.get("aliyun.prefix");
    }

    /**
     * 私有化構造
     */
    private AliyunOSSUtils() {

    }

    /**
     * 獲取圖片的URL頭信息
     *
     * @return 返回url頭信息
     */
    private static String getURLHead() {
        //從哪一個位置截取
        int cutPoint = endpoint.lastIndexOf('/') + 1;
        //http頭
        String head = endpoint.substring(0, cutPoint);
        //服務器地址信息
        String tail = endpoint.substring(cutPoint);
        //返回結果
        return head + bucketName + "." + tail + "/";
    }

    /**
     * 獲取存儲在服務器上的地址
     *
     * @param oranName 文件名
     * @return 文件URL
     */
    private static String getRealName(String oranName) {
        return getURLHead() + oranName;
    }

    /**
     * 獲取一個隨機的文件名
     *
     * @param oranName 初始的文件名
     * @return 返回加uuid後的文件名
     */
    private static String getRandomImageName(String oranName) {
        //獲取一個uuid 去掉-
        String uuid = UUID.randomUUID().toString().replace("-", "");
        //查一下是否帶路徑
        int cutPoint = oranName.lastIndexOf("/") + 1;
        //若是存在路徑
        if (cutPoint != 0) {
            //掐頭 若是開頭是/ 則去掉
            String head = oranName.indexOf("/") == 0 ? oranName.substring(1, cutPoint) : oranName.substring(0, cutPoint);
            //去尾
            String tail = oranName.substring(cutPoint);
            //返回正確的帶路徑的圖片名稱
            return file_prefix + head + uuid + tail;
        }
        //不存在 直接返回
        return file_prefix + uuid + oranName;
    }

    /**
     * MultipartFile2File
     * @param multipartFile
     * @return
     */
    private static File transferToFile(MultipartFile multipartFile) {
        //選擇用緩衝區來實現這個轉換即便用java 建立的臨時文件 使用 MultipartFile.transferto()方法 。
        File file = null;
        try {
            //獲取文件名
            String originalFilename = multipartFile.getOriginalFilename();
            //獲取最後一個"."的位置
            int cutPoint = originalFilename.lastIndexOf(".");
            //獲取文件名
            String prefix = originalFilename.substring(0,cutPoint);
            //獲取後綴名
            String suffix = originalFilename.substring(cutPoint + 1);
            //建立臨時文件
            file = File.createTempFile(prefix, suffix);
            //multipartFile2file
            multipartFile.transferTo(file);
            //刪除臨時文件
            file.deleteOnExit();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return file;
    }

    /**
     * 上傳文件流
     *
     * @param oranFileName 上傳到服務器上的文件路徑和名稱
     * @param file         來自本地的文件或者文件流
     */
    public static String uploadFileInputSteam(String oranFileName, MultipartFile file) {

        // <yourObjectName>上傳文件到OSS時須要指定包含文件後綴在內的完整路徑,例如abc/efg/123.jpg
        String objectName = getRandomImageName(oranFileName);

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

        // 上傳文件流
        try (InputStream inputStream = new FileInputStream(transferToFile(file))) {
            //上傳到OSS
            ossClient.putObject(bucketName, objectName, inputStream);
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        // 關閉OSSClient。
        ossClient.shutdown();

        //返回文件在服務器上的全路徑+名稱
        return getRealName(objectName);
    }


    /**
     * 上傳文件流
     *
     * @param oranFileName 上傳到服務器上的文件路徑和名稱
     * @param file         來自本地的文件或者文件流
     */
    public static String uploadFileInputSteam(String oranFileName, File file) {

        // <yourObjectName>上傳文件到OSS時須要指定包含文件後綴在內的完整路徑,例如abc/efg/123.jpg
        String objectName = getRandomImageName(oranFileName);

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

        // 上傳文件流。
        try (InputStream inputStream = new FileInputStream(file);) {
            //上傳到OSS
            ossClient.putObject(bucketName, objectName, inputStream);
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        // 關閉OSSClient。
        ossClient.shutdown();

        //返回文件在服務器上的全路徑+名稱
        return getRealName(objectName);
    }

}

SpringBoot+表單上傳測試

前端代碼

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文件上傳</title>
</head>
<body>
    <h1>文件上傳Demo</h1>
    <hr>
    <form id="myform" action="/upload" method="post" enctype="multipart/form-data">
        <input type="file" name="file">
        <input type="submit" value="提交">
    </form>
</body>
</html>

後臺代碼

package cn.rayfoo.controller;

import cn.rayfoo.utils.AliyunOSSUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;

/**
 * @Author: rayfoo@qq.com
 * @Date: 2020/7/13 3:15 下午
 * @Description:
 */
@RestController
public class FileController {

    @PostMapping("/upload")
    public String upload(@RequestParam("file")MultipartFile file, HttpServletRequest request){
        //若是文件爲空 返回錯誤信息
        if(file.isEmpty()){
            return "field";
        }
        //獲取原文件名
        String originalFilename = file.getOriginalFilename();

        //返回圖片的url
       return AliyunOSSUtils.uploadFileInputSteam(originalFilename,file);
    }

}
相關文章
相關標籤/搜索