1. 程式人生 > 實用技巧 >阿里雲OSS上手指導(下)

阿里雲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用的開心!