阿里雲OSS上手指導(下)
在上一篇中我們講了OSS是什麼?為什麼要用?以及怎樣選購和配置。本篇我們主要來看看怎樣使用,我們以Java和PHP兩種語言來示範。
在OSS控制檯右側的Bucket管理介面上,我們可以看到官方提供的新手入門和API文件:
我們就以PHP語言來演示如何通過API的方式接入OSS。首先,在常用入口那兒可以查詢到Access Key,包括一對AccessKey ID和AccessKey Secret。無論是通過API還是SDK方式接入,這兩個引數都是必須的。其實,檔案上傳到OSS上和檔案上傳到我們自己伺服器上的流程,並沒有多少區別,我們還是會用HTTP協議,通過FORM表單的形式提交資料。不同在於構建這個header頭的引數有些差異罷了。OSS要求我們在header頭中,攜帶一個Authorization引數,用於驗證客戶端身份。所以重點就是圍繞如何構建這個引數,還實現HTTP協議的通訊。
既然和我們傳統http的form表單上傳差異在header上,我們不妨就從header入手。首先定義一個數組來放置我們的header引數:
//GMT時間
$date = gmdate('D, d M Y H:i:s T');
//mime
$mime = 'image/png';
//構建報頭
$header = array(
'Host' => 'oss.aliyuncs.com',
'Date' => $date,
'Content-Type' => $mime
);
如上示例定義的header頭中,包含了一個Host用於指定HTTP協議送達的主機域,另外,OSS的API文件中,要求我們提供一個Date引數來表示時間,格式使用GMT。最後,Content-Type引數來表明我們上傳的檔案格式。為了演示方便,我們這裡寫死為"image/png",表示上傳的是png格式的圖片。讀者可以根據自身業務邏輯來獲取並傳遞這個MIME。
還記得我們上一篇中建立的Bucket名字麼?這裡就派上用場了,我們得指定檔案往哪上傳,以為OSS中可能不止一個bucket。通常這個資源識別符號是這樣的:
倉庫(bucket)名稱 + 目錄名稱 + 檔名
假設我們在名為1doc的bucket中有個目錄叫做images,現在要上傳defult.png檔案到這個目錄中,那麼uri就應該是這樣子的:
1doc/images/default.png
我們把這個資源識別符號儲存到一個變數中,待會使用:
$bucketMame = '1doc'; $menu = '/images/'; $fileName = 'default.png'; $savePath = $bucketName . $menu . $fileName;
那麼重點來了,我們要開始準備構建Authorization引數了。
第一步根據API文件中的指導精神,我們遵循HTTP協議,通過PUT方式來上傳檔案,拼接出請求頭:
$signStr = "PUT\n" . $mime . "\n" . $date . "\n" . $savePath;
第二步,通過sha1演算法將上面這個待簽名的字串和AccessKey Secret加密,再用base64編碼:
$signature = base64_encode(hash_mac('sha1', $signStr, $accessKeySecret, true));
第三步,使用AccessKey ID 與上面的簽名字元拼接成最終的Authorization,並加到header頭中:
$sign = 'OSS ' . $accessKeyID . ':' . $signture;
$header['Authorization'] = $sign;
接下來的事兒就簡單了,就是普通的HTTP請求了。當然,我們先準備好要上傳的檔案:
$file = file_get_contents('default.png');
然後通過curl來提交請求:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://oss.aliyuncs.com/' . $savePath);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$result = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
return $info['http_code'];
對於PHP而言,筆者注意到OSS近來已經支援composer來引入SDK了,相較於早些年自己去載入.php檔案要方便的多。所以,除非沒有更好的解決方案,筆者還是建議使用SDK來整合。
SDK方式接入OSS
我們用java來演示通過sdk的方式接入OSS。筆者的專案使用Maven構建的,在Maven的pom.xml可以很方便地引入OSS SDK依賴:
<!-- 阿里雲oss元件 -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.10.2</version>
</dependency>
我們在控制器中定義一個action用來接收客戶端的form表單資料,並上傳到OSS中:
@RestController
public class ResourceController {
@PostMapping("upload.do")
public JsonResult upload(MultipartFile file) {
//具體上傳邏輯
}
}
現在我們來準備一些引數吧,包括AccessKey ID和AccessKey Secret,還有Bucket名字。
String accessKey = "your key";
String accessSecret = "your secret";
String bucketName = "1doc";
String endpoint = "http://oss-cn-shanghai.aliyuncs.com"
相對於API的繁瑣,java的SDK提供了一個OSSClient來幫我們構建請求客戶端,我們稍加封裝成一個方法,以供不同的操作使用:
private OSS getClient() {
return new OSSClientBuilder().build(endpoint, accessKey, accessSecret)
}
我們可以通過這個client去操作OSS檔案的上傳、下載、更新以及刪除等操作,不必關係身份驗證等細節問題。
來瞧瞧上傳一個檔案是多麼的簡單:
OSS ossClient = getClient();
ossClient.putObject(bucketName, fileName, inputStream);
ossClient.shutdown();
OSSClient物件中提供的putObject()方法用來上傳檔案,當然putObject有多個過載的方法,以上是以檔案流的方式上傳。
我們在控制器中接收到來自客戶端form表單資料的 MultipartFile,通過getInputStream()方法就可以獲得一個檔案流,在這裡傳入就可以了。
除了putObject()方法,OSSClient物件還提供了諸多的操作OSS檔案的方法,包括常用的增刪改查,諸如此類無需再演示。
此致,祝你OSS用的開心!