用云存储30分钟快速搭建APP
背景
不管你承認(rèn)與否,移動(dòng)互聯(lián)的時(shí)代已經(jīng)到來(lái),這是一個(gè)移動(dòng)互聯(lián)的時(shí)代,手機(jī)已經(jīng)是當(dāng)今世界上引領(lǐng)潮流的趨勢(shì),大型的全球化企業(yè)和中小企業(yè)都把APP程序開(kāi)發(fā)納入到他們的企業(yè)發(fā)展策略當(dāng)中。
但隨著手機(jī)APP上傳的數(shù)據(jù)會(huì)越來(lái)越多,任何企業(yè)系統(tǒng)、應(yīng)用的軟件都必須解決這一問(wèn)題,數(shù)據(jù)存儲(chǔ)必須以某種方式保存,不能丟失并且能夠有效簡(jiǎn)單地使用和更新這些數(shù)據(jù)。如果開(kāi)發(fā)者自行解決數(shù)據(jù)存儲(chǔ)的問(wèn)題,有可能在后期花費(fèi)在之上的精力是其他方面的數(shù)倍,但是如果將數(shù)據(jù)存儲(chǔ)這一問(wèn)題交給OSS,那么開(kāi)發(fā)者就可以從中得以解放,更加專注于自己的應(yīng)用邏輯。
目的
本文的目的就是讓你在30分鐘內(nèi)搭建一個(gè)基于OSS的移動(dòng)應(yīng)用數(shù)據(jù)直傳服務(wù),所謂直傳就是移動(dòng)應(yīng)用的數(shù)據(jù)的上傳和下載直接直連OSS,只有控制流走用戶自己的服務(wù)器,并且具有如下特點(diǎn):
- 安全的上傳下載方式(臨時(shí),靈活的賦權(quán)鑒權(quán)),
- 成本低(這樣用戶不需要準(zhǔn)備很多服務(wù)器,因?yàn)橐苿?dòng)應(yīng)用直聯(lián)云存儲(chǔ),只有控制流走用戶自己的應(yīng)用服務(wù)器。)
- 高并發(fā),支持海量用戶(OSS有海量的上傳和下載帶寬)
- 彈性(OSS有無(wú)限擴(kuò)容的存儲(chǔ)空間)
- 方便(可以方便的對(duì)接到媒體轉(zhuǎn)碼服務(wù)-視頻多端適配,圖片處理服務(wù),CDN加速下載等)
架構(gòu)圖
詳細(xì)資料可以參考這里
角色解析
數(shù)據(jù)流解析
本文主要介紹了下圖中紅色和藍(lán)色框的內(nèi)容:
應(yīng)用服務(wù)器如何生成這個(gè)Token,藍(lán)色方框
Android/iOS應(yīng)用如何取Token,紅色方框
效果
本文實(shí)現(xiàn)了一個(gè)APP,如下,大家可以掃描二維碼,安裝一下示例APP程序,這上工具是用Android開(kāi)發(fā)。 但是本文的應(yīng)用服務(wù)器搭建也適用于iOS, 即上述圖藍(lán)色的框的內(nèi)容。
示例程序的體驗(yàn)
示例程序的最終效果圖如下:
示例APP的使用
可以點(diǎn)擊選擇圖片,然后就把文件上傳到OSS,上傳的方法,支持普通上傳和斷點(diǎn)上傳。注意在一些網(wǎng)絡(luò)環(huán)境差的環(huán)境下,最好用斷點(diǎn)上傳。然后可以利用圖片處理服務(wù),可以對(duì)將上傳的圖片進(jìn)行縮略和加水印處理。初始使用請(qǐng)暫時(shí)先不要改應(yīng)用服務(wù)器地址和Bucket名字。
搭建這樣一個(gè)APP上傳和下載的系統(tǒng) ,需要準(zhǔn)備的東西:
必須開(kāi)通了OSS,并且創(chuàng)建了Bucket, 在這個(gè)例子里面的,對(duì)應(yīng)的bucket是 :sdk-demo;
必須開(kāi)通STS服務(wù)。開(kāi)通STS服務(wù)其實(shí)是為了如何生成上述所描述的Token;
必須搭建這樣一個(gè)應(yīng)用服務(wù)器。這在個(gè)事例里面,我搭建的應(yīng)用服務(wù)器的地址是:http://oss-demo.aliyuncs.com/app-server/sts.php . 注意這個(gè)例子本文是采用PHP編寫(xiě)的,但是事實(shí)上,用戶可以選擇自己喜歡的語(yǔ)言進(jìn)行編寫(xiě),如Java 、Python、 Go、Ruby、Node.js、C#等編寫(xiě)。
為帳號(hào)開(kāi)通STS服務(wù)
(1)要開(kāi)通STS服務(wù),首先OSS登陸官網(wǎng)控制臺(tái)
(2)登錄管理控制臺(tái),點(diǎn)擊:安全令牌快捷配置
(3)會(huì)進(jìn)入到令牌快捷配置頁(yè)面,注意如果沒(méi)有開(kāi)通RAM,會(huì)彈出開(kāi)通的對(duì)話框。直接點(diǎn)開(kāi)通,這個(gè)要求實(shí)名驗(yàn)證。 做完后跳到本頁(yè)面。點(diǎn)擊開(kāi)始授權(quán)
(4)點(diǎn)擊開(kāi)始授權(quán)后,系統(tǒng)會(huì)進(jìn)行自動(dòng)授權(quán),請(qǐng)千萬(wàn)保存如下圖框住的三個(gè)參數(shù)
點(diǎn)擊保存AK信息后,對(duì)話框會(huì)關(guān)閉。保存好下面標(biāo)紅的結(jié)果3。
保存這三個(gè)參數(shù)后。到這一步,STS的開(kāi)通已經(jīng)完成了。
注意如果您之前已經(jīng)點(diǎn)擊這個(gè)頁(yè)面創(chuàng)建了AccessKeyId/AccessKeySecrte, 彈出的頁(yè)面如下:
點(diǎn)擊如下圖所示的查看
點(diǎn)擊如下圖所示的創(chuàng)建AccessKey
記下如下參數(shù)1,2
并記下如下參數(shù)3:
保存這三個(gè)參數(shù)后。到這一步,STS的開(kāi)通已經(jīng)完成了。
講解一下應(yīng)用服務(wù)器的搭建
為了方便大家開(kāi)發(fā)。 本文準(zhǔn)備了三個(gè)語(yǔ)言的版本示例程序 (Java、PHP、Ruby)。
應(yīng)用服務(wù)器代碼示例的下載
PHP: 下載地址
Java: 下載地址
Ruby: 下載地址
應(yīng)用服務(wù)器示例的配置
每個(gè)語(yǔ)言包下載下來(lái)后,都會(huì)有一個(gè)配置文件config.json。
如下例:
{
"AccessKeyID" : "",
"AccessKeySecret" : "",
"RoleArn" : "",
"TokenExpireTime" : "900",
"PolicyFile": "policy/all_policy.txt"
}
下面對(duì)配置進(jìn)行講解。
如果你想要指定這個(gè)Token只能對(duì)指定的bucket有讀寫(xiě)權(quán)限, 請(qǐng)把(bucket_read_policy.txt、 bucket_read_write_policy.txt)這個(gè)文件里面$BUCKET_NAME直接替換成指定的bucket名字。返回的格式解析。
{
"status":200,
"AccessKeyId":"STS.3pYjsdgdgagdasdg",
"AccessKeySecret":"rpnwO9kvEgetGdrddgsR2YrTtI",
"Security":"CAES+wMIARKAAZhjH0EUOIhJMQBMjRywXq7MQ/cjLYg80Aho1ek0Jm63XMhr9Oc5s˙?˙?3qaPer8p1YaX1NTDiCFZWFkvlHf1pQhuxfKBc+mRR9KAbHUefqH+rdjZqjTF7p2m1wJXP8S6k+G2MpHrUe6TYBkJ43GhhTVFMuM3BZajY3VjZWOXBIODRIR1FKZjIiEjMzMzE0MjY0NzM5MTE4NjkxMSoLY2xpZGSSDgSDGAGESGTETqOio6c2RrLWRlbW8vKgoUYWNzOm9zczoqOio6c2RrLWRlbW9KEDExNDg5MzAxMDcyNDY4MThSBTI2ODQyWg9Bc3N1bWVkUm9sZVVzZXJgAGoSMzMzMTQyNjQ3MzkxMTg2OTExcglzZGstZGVtbzI=",
"Expiration":"2015-12-12T07:49:09Z",
}
- status:表示獲取Token的狀態(tài),獲取成功時(shí),返回值是200
- AccessKeyId: 表示Android/iOS應(yīng)用初始化OSSClient獲取的 AccessKeyId
- AccessKeySecret: 表示Android/iOS應(yīng)用初始化OSSClient獲取AccessKeySecret
- SecurityToken:表示Android/iOS應(yīng)用初始化的Token
- Expiration: 表示該Token失效的時(shí)間。主要在Android SDK會(huì)自動(dòng)判斷是否失效,自動(dòng)獲取Token
注意上述這四個(gè)變量將構(gòu)成了一個(gè)Token。
代碼示例的運(yùn)行方法
對(duì)于PHP版本
PHP運(yùn)行的,將包下載 后,然后修改好config.json這個(gè)文件。直接運(yùn)行php sts.php 即能生成Token,將程序部署到指定的地址。
對(duì)于JAVA版本 (依賴于java 1.7)
下載編譯好的jar 包,下載地址:
下載后解壓:
運(yùn)行方法:java -jar oss-token-server.jar (port)
如果不指定port(端口), 直接運(yùn)行java –jar oss-token-server.jar , 程序會(huì)監(jiān)聽(tīng)7080端口
如果想讓程序執(zhí)行在9000端口,運(yùn)行java –jar oss-token-server.jar 9000 , 其他端口也類似。
體驗(yàn)自己的APP上傳應(yīng)用服務(wù)器
核心代碼解析-OSS初始化
下面講解一下如何 利用Android/iOS SDK跟自己的應(yīng)用服務(wù)器,請(qǐng)求Token。
Android版本
//初始化一個(gè)OssService用來(lái)上傳下
public OssService initOSS(String endpoint, String bucket, UIDisplayer displayer) {
OSSCredentialProvider credentialProvider;
//使用自己的獲取STSToken的類
//從應(yīng)用服務(wù)器控件里面讀取應(yīng)用服務(wù)器地址
String stsServer = ((EditText) findViewById(R.id.stsserver)).getText().toString();
//STSGetter類,封裝如何跟從應(yīng)用服務(wù)器取數(shù)據(jù),必須繼承于OSSFederationCredentialProvider這個(gè)類。 取Token這個(gè)取決于你所寫(xiě)的APP跟應(yīng)用服務(wù)器數(shù)據(jù)的協(xié)議設(shè)計(jì)。
if (stsServer .equals("")) {
credentialProvider = new STSGetter();
}else {
credentialProvider = new STSGetter(stsServer);
}
//獲取控件上的bucket名字
bucket = ((EditText) findViewById(R.id.bucketname)).getText().toString();
//初始化OSSClient
ClientConfiguration conf = new ClientConfiguration();
conf.setConnectionTimeout(15 * 1000); // 連接超時(shí),默認(rèn)15秒
conf.setSocketTimeout(15 * 1000); // socket超時(shí),默認(rèn)15秒
conf.setMaxConcurrentRequest(5); // 最大并發(fā)請(qǐng)求書(shū),默認(rèn)5個(gè)
conf.setMaxErrorRetry(2); // 失敗后最大重試次數(shù),默認(rèn)2次
OSS oss = new OSSClient(getApplicationContext(), endpoint, credentialProvider, conf);
return new OssService(oss, bucket, displayer);
}
iOS版本
// 初始化一個(gè)OSSClient實(shí)例
- (void)ossInit {
// 構(gòu)造一個(gè)獲取STSToken的憑證提供器
id<OSSCredentialProvider> credential = [[OSSFederationCredentialProvider alloc] initWithFederationTokenGetter:^OSSFederationToken * {
// 實(shí)現(xiàn)一個(gè)函數(shù),同步返回從server獲取到的STSToken
return [self getFederationToken];
}];
// 用endpoint、憑證提供器初始化一個(gè)OSSClient
client = [[OSSClient alloc] initWithEndpoint:endPoint credentialProvider:credential];
}
核心代碼解析-移動(dòng)應(yīng)用從應(yīng)用服務(wù)器取Token
具體APP從就應(yīng)用服務(wù)器取Token方法,必須寫(xiě)到public OSSFederationToken getFederationToken() { } 這個(gè)函數(shù)里面。
注意這個(gè)函數(shù)的邏輯依賴于可以自己設(shè)定,但是最終結(jié)果必須返回這樣一個(gè)變量 return new OSSFederationToken(ak, sk, token, expiration);
其中ak, sk, token, expiration 必須是從應(yīng)用服務(wù)器返回的Body獲取的。
在本例子里,示例如下,注意用戶可以自定義自己的移動(dòng)應(yīng)用跟自己應(yīng)用服務(wù)器之前的協(xié)議。
Android版本
public OSSFederationToken getFederationToken() {
String stsJson;
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(stsServer).build();
try {
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
stsJson = response.body().string();
} else {
throw new IOException("Unexpected code " + response);
}
}
catch (IOException e) {
e.printStackTrace();
Log.e("GetSTSTokenFail", e.toString());
return null;
}
try {
JSONObject jsonObjs = new JSONObject(stsJson);
String ak = jsonObjs.getString("AccessKeyId");
String sk = jsonObjs.getString("AccessKeySecret");
String token = jsonObjs.getString("SecurityToken");
String expiration = jsonObjs.getString("Expiration");
return new OSSFederationToken(ak, sk, token, expiration);
}
catch (JSONException e) {
Log.e("GetSTSTokenFail", e.toString());
e.printStackTrace();
return null;
}}
iOS版本
NSURL * url = [NSURL URLWithString:STSServer];
NSURLRequest * request = [NSURLRequest requestWithURL:url];
OSSTaskCompletionSource * tcs = [OSSTaskCompletionSource taskCompletionSource];
NSURLSession * session = [NSURLSession sharedSession];
NSURLSessionTask * sessionTask = [session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
[tcs setError:error];
return;
}
[tcs setResult:data];
}];
[sessionTask resume];
// 實(shí)現(xiàn)這個(gè)回調(diào)需要同步返回Token,所以要waitUntilFinished
[tcs.task waitUntilFinished];
if (tcs.task.error) {
// 如果網(wǎng)絡(luò)請(qǐng)求出錯(cuò),返回nil表示無(wú)法獲取到Token。該次請(qǐng)求OSS會(huì)失敗。
return nil;
} else {
// 從網(wǎng)絡(luò)請(qǐng)求返回的內(nèi)容中解析JSON串拿到Token的各個(gè)字段,組成STSToken返回
NSDictionary * object = [NSJSONSerialization JSONObjectWithData:tcs.task.result
options:kNilOptions
error:nil];
OSSFederationToken * token = [OSSFederationToken new];ni
token.tAccessKey = [object objectForKey:@"AccessKeyId"];
token.tSecretKey = [object objectForKey:@"AccessKeySecret"];
token.tToken = [object objectForKey:@"SecurityToken"];
token.expirationTimeInGMTFormat = [object objectForKey:@"Expiration"];
return token;
}
OSS相關(guān)功能的代碼,可以查看示例程序的實(shí)現(xiàn)
該Android示例程序的源碼下載地址
該iOS示例程序的源碼下載地址
應(yīng)用服務(wù)器代碼示例的下載
PHP: 下載地址
Java: 下載地址
Ruby: 下載地址
總結(jié)
以上是生活随笔為你收集整理的用云存储30分钟快速搭建APP的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: eclipse怎样在线安装hiberna
- 下一篇: TCP/IP——基本知识