一、七牛雲的對象存儲的介紹
七牛雲對象存儲 Kodo 是七牛雲提供的高可靠、強安全、低成本、可擴展的存儲服務。您可通過控制檯、API、SDK 等方式簡單快速地接入七牛存儲服務,實現海量數據的存儲和管理。通過 Kodo 可以進行文件的上傳、下載和管理。
此外,Kodo 的姊妹產品融合 CDN可以對文件下載進行加速,智能多媒體 API更是提供了豐富的基於海量數據深度學習算法的計算機視覺服務,如人臉技術、場景物體識別、OCR 文字識別和內容審覈等。
二、七牛雲對象存儲(Kodo)主要應用場景
- 在線存儲和分發
七牛雲對象存儲提供高可用和高可靠的對象存儲服務,您可以放心的將各種內容存儲在雲端。利用七牛雲對象存儲的擴展性和按需付費的優勢,可以滿足您持續快速增長的存儲需求。您也可以搭配使用七牛雲的對象存儲和融合 CDN服務,實現全球覆蓋、快速高效的內容分發。
- 鏡像存儲
七牛雲對象存儲支持鏡像存儲,這是一種快速的數據遷移和加速服務。可以幫助您實現無縫數據遷移,遷移過程中並不影響原有業務系統的訪問。鏡像存儲適用於遷移原有業務系統的已有數據。
- 備份和歸檔
七牛雲對象存儲提供高可用和高可靠的存儲解決方案來備份和歸檔您的關鍵數據。通過七牛雲的身份驗證機制可以設置不同的訪問權限和級別,保障您數據的訪問安全。相比傳統自建的備份和歸檔存儲系統,您無需在業務初期採購高昂硬件,無需擔心數據增長帶來的擴容問題,從而節省更多的存儲成本、維護成本和人力資源成本。
- 富媒體數據處理
針對海量的用戶生成內容,七牛雲對象存儲能夠提供跨地域、高併發的內容上傳和訪問服務。同時結合七牛雲提供的數據處理服務,可以在雲端實現圖片裁剪、格式轉化和水印,以及視頻轉碼、切片和拼接等富媒體處理功能,滿足移動網絡場景下多終端設備的訪問需求。
- 靜態資源託管
七牛雲對象存儲無縫集合各類第三方擴展插件,如 WordPress、Discuz、Emlog 等,並支持一鍵將各類插件裏的靜態資源託管到七牛雲對象存儲。
三、使用Java進行開發
-
整合七牛雲SDK
在Maven中添加七牛雲SDK依賴包:<dependencies> <dependency> <groupId>com.qiniu</groupId> <artifactId>qiniu-java-sdk</artifactId> <version>7.2.11</version> <scope>compile</scope> </dependency> <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>3.3.1</version> <scope>compile</scope> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.6.2</version> <scope>compile</scope> </dependency> <dependency> <groupId>com.qiniu</groupId> <artifactId>happy-dns-java</artifactId> <version>0.1.4</version> <scope>compile</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies>
最新官方SDK開發文檔地址:https://developer.qiniu.com/kodo/sdk/1239/java#3
-
上傳文件原理
根據官方的開發手冊可以知道,七牛雲服務器接受從客戶端直接上傳文件,之後再通過回調地址發送回調,對於返回的數據也給了我們很大的自由,我們完全可以自定義需要返回的數據。也可以從本地直接上傳文件,原理與從客戶端上傳相似,這裏不再贅述。
七牛雲上傳文件開發手冊鏈接:https://developer.qiniu.com/kodo/manual/1272/form-upload
七牛雲的倉庫有兩種,公開倉庫和私有倉庫,這兩種倉庫上傳的原理相似。七牛雲的對象存儲類似於java中的Map,使用的是鍵-值的存儲方式,鍵是唯一的,我們可以通過鍵來改變它所對應的值,所以我們在上傳的時候一定要注意保證鍵的唯一。
那麼七牛雲是怎麼知道是誰在上傳,他應該把上傳的文件放在哪裏呢?很簡單,通過密鑰
我們需要先設置七牛雲的密鑰,在使用的時候通過密鑰生成一個通行證,也就是七牛雲的上傳憑證,這個上傳憑證中包含了你上傳文件所需要的所有信息,七牛雲可以通過這個通行證得到他所需要的信息。
首先,我們來設置密鑰:
- 打開七牛雲
- 登錄七牛雲賬號,進入個人中心
- 直接生成密鑰就可以了
有了密鑰以後,我們就可以通過密鑰來生成上傳憑證了。這裏我封裝了七牛雲上傳工具類,直接看工具類吧
package com.kude.controller; import com.qiniu.util.Auth; import com.qiniu.util.StringMap; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.Properties; public class Qiniu { // accessKey private static String accessKey = "access key"; // secretKey private static String secretKey = "secret key"; // public Bucket private static String publicBucket = "bucket name"; // private Bucket private static String privateBucket= "privateBucket"; // 回調地址 private static String callbackURL = "callBackURL"; //publicIMGURL private static String publicIMGURL = "IMGURL"; // priviteIMGURL private static String priviteIMGURL = "priviteIMGURL"; // 靜態加載配置文件中的數據 static{ try { FileInputStream in = new FileInputStream("D:\\demo\\svn\\cloud_demo\\cloud_demo\\src\\main\\resources\\datasource.properties"); Properties properties = new Properties(); properties.load(in); accessKey = properties.getProperty("AccessKey"); secretKey = properties.getProperty("SecretKey"); publicBucket = properties.getProperty("publicBucket"); privateBucket = properties.getProperty("privateBucket"); callbackURL = properties.getProperty("CallBackURL"); publicIMGURL = properties.getProperty("publicIMGURL"); priviteIMGURL = properties.getProperty("priviteIMGURL"); in.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * * 得到上傳憑證和資源下載路徑 * @param bocket 指定是在共有倉庫還是私有倉庫中,0爲私有倉庫,非0爲共有倉庫 * @param key 資源的key * @return 一個存有上傳憑證 */ public static Map<String,String> getUploadToken(int bocket, String key){ Map<String,String> data = new HashMap<>(); // 將上傳憑證放入map中 data.put("token",getuplodTokenByKey(key)); // 圖片地址 data.put("url",getUrl(bocket,key)); return data; } /** * 得到資源的訪問地址,也是下載地址 * @param bocket 指定是在共有倉庫還是私有倉庫中,0爲私有倉庫,非0爲共有倉庫 * @param key 資源的key * @return 資源的訪問地址 */ private static String getUrl(int bocket,String key){ if(bocket == 0){ return getstaticDownloadToken(priviteIMGURL+key); }else{ return publicIMGURL+key; } } public static String getuplodTokenByKey(String key){ // 第一步: 先生成一個Auth驗證 Auth auth = Auth.create(accessKey, secretKey); // 第二步: 使用StringMap工具類拼裝參數 StringMap putPolicy = new StringMap(); /* * 指定上傳的目標資源空間 Bucket 和資源鍵 Key(最大爲 750 字節)。有三種格式: * 1. <bucket>,表示允許用戶上傳文件到指定的 bucket。在這種格式下文件只能新增 * (分片上傳需要指定insertOnly爲1纔是新增,否則也爲覆蓋上傳),若已存在同名資源(且文件內容/etag不一致), * 上傳會失敗;若已存在資源的內容/etag一致,則上傳會返回成功。 * * * 2. <bucket>:<key>,表示只允許用戶上傳指定 key 的文件。 * 在這種格式下文件默認允許修改,若已存在同名資源則會被覆蓋。 * 如果只希望上傳指定 key 的文件,並且不允許修改,那麼可以將下面的 insertOnly 屬性值設爲 1。 * * * 3. <bucket>:<keyPrefix>,表示只允許用戶上傳指定以 keyPrefix 爲前綴的文件, * 當且僅當 isPrefixalScope 字段爲 1 時生效,isPrefixalScope 爲 1 時無法覆蓋上傳。 * * type : String * */ putPolicy.put("scope",publicBucket); // 上傳憑證有效截止時間。Unix時間戳,單位爲秒。該截止時間爲上傳完成後,在七牛空間生成文件的校驗時間, // 而非上傳的開始時間,一般建議設置爲上傳開始時間 + 3600s // type : uint32 putPolicy.put("deadline",(System.currentTimeMillis()/1000L + 3600)); // Web 端文件上傳成功後,瀏覽器執行 303 跳轉的 URL。通常用於表單上傳。文件上傳成功後會跳轉到 // <returnUrl>?upload_ret=<queryString>,<queryString>包含 returnBody 內容。 // 如不設置 returnUrl,則直接將 returnUrlnBody 的內容返回給客戶端。 // type : String // putPolicy.put("returnUrl",""); /* *上傳成功後,自定義七牛雲最終返回給上傳端(在指定 returnUrl 時是攜帶在跳轉路徑參數中)的數據。 * 支持魔法變量和自定義變量。returnBody 要求是合法的 JSON 文本。 * 例如 {"key": $(key), "hash": $(etag), "w": $(imageInfo.width), "h": $(imageInfo.height)}。 */ // type : String putPolicy.put("returnBody","{\"key\": $(key), \"hash\": $(etag), \"w\": $(imageInfo.width), \"h\": $(imageInfo.height)}"); /* * * 上傳成功後,七牛雲向業務服務器發送 Content-Type: application/x-www-form-urlencoded 的 POST 請求。 * 業務服務器可以通過直接讀取請求的 query 來獲得該字段,支持魔法變量和自定義變量。 * callbackBody 要求是合法的 url query string。 * 例如key=$(key)&hash=$(etag)&w=$(imageInfo.width)&h=$(imageInfo.height)。 * 如果callbackBodyType指定爲application/json,則callbackBody應爲json格式, * 例如:{"key":"$(key)","hash":"$(etag)","w":"$(imageInfo.width)","h":"$(imageInfo.height)"}。 * */ // type : String putPolicy.put("callbackBody","{\"key\":\"$(key)\",\"hash\":\"$(etag)\",\"w\":\"$(imageInfo.width)\",\"h\":\"$(imageInfo.height)\"}"); //上傳成功後,七牛雲向業務服務器發送回調通知 callbackBody 的 Content-Type。 // 默認爲 application/x-www-form-urlencoded,也可設置爲 application/json。 // type : String putPolicy.put("callbackBodyType","application/json"); // 第三步: 生成一個上傳憑證 return auth.uploadToken(publicBucket,key,(System.currentTimeMillis()/1000L+3600),putPolicy); } /** * 獲得一個私有空間下載的憑證,傳入的參數是按照公開倉庫訪問方式生成的URL * @param baseUrl 按照公開倉庫生成URL的方式生成的URL * @return */ public static String getstaticDownloadToken(String baseUrl){ Auth auth = Auth.create(accessKey, secretKey); return auth.privateDownloadUrl(baseUrl); } /** * 指定在七牛雲上面的存儲路徑 * @return */ public String getDynamicUpToken(String resporties){ Auth auth = Auth.create(accessKey, secretKey); StringMap putPolicy = new StringMap(); putPolicy.put("scope",resporties); putPolicy.put("deadline",(System.currentTimeMillis()/1000L + 3600)); putPolicy.put("returnBody","{\"key\": $(key), \"hash\": $(etag), \"w\": $(imageInfo.width), \"h\": $(imageInfo.height)}"); putPolicy.put("callbackBody","{\"key\":\"$(key)\",\"hash\":\"$(etag)\",\"w\":\"$(imageInfo.width)\",\"h\":\"$(imageInfo.height)\"}"); putPolicy.put("callbackBodyType","application/json"); return auth.uploadToken(publicBucket,null,(System.currentTimeMillis()/1000L+3600),putPolicy); } /** * 可以根據需求自己封裝要生成的憑證 * 默認得到一個6分鐘後過期的動態上傳憑證,這個憑證可以讓文件上傳到默認倉庫中 * * 這個是所有上傳憑證的原型,不能動 * * @return */ public static String getDefaultDynamicUpToken(){ // 第一步: 先生成一個Auth驗證 Auth auth = Auth.create(accessKey, secretKey); // 第二步: 使用StringMap工具類拼裝參數 StringMap putPolicy = new StringMap(); /* * 指定上傳的目標資源空間 Bucket 和資源鍵 Key(最大爲 750 字節)。有三種格式: * 1. <bucket>,表示允許用戶上傳文件到指定的 bucket。在這種格式下文件只能新增 * (分片上傳需要指定insertOnly爲1纔是新增,否則也爲覆蓋上傳),若已存在同名資源(且文件內容/etag不一致), * 上傳會失敗;若已存在資源的內容/etag一致,則上傳會返回成功。 * * * 2. <bucket>:<key>,表示只允許用戶上傳指定 key 的文件。 * 在這種格式下文件默認允許修改,若已存在同名資源則會被覆蓋。 * 如果只希望上傳指定 key 的文件,並且不允許修改,那麼可以將下面的 insertOnly 屬性值設爲 1。 * * * 3. <bucket>:<keyPrefix>,表示只允許用戶上傳指定以 keyPrefix 爲前綴的文件, * 當且僅當 isPrefixalScope 字段爲 1 時生效,isPrefixalScope 爲 1 時無法覆蓋上傳。 * * type : String * */ putPolicy.put("scope",publicBucket); // 若爲 1,表示允許用戶上傳以 scope 的 keyPrefix 爲前綴的文件。 // type : int // putPolicy.put("isPrefixalScope",1); // 上傳憑證有效截止時間。Unix時間戳,單位爲秒。該截止時間爲上傳完成後,在七牛空間生成文件的校驗時間, // 而非上傳的開始時間,一般建議設置爲上傳開始時間 + 3600s // type : uint32 putPolicy.put("deadline",(System.currentTimeMillis()/1000L + 3600)); // 限定爲新增語意。如果設置爲非 0 值,則無論 scope 設置爲什麼形式,僅能以新增模式上傳文件。 // type : int // putPolicy.put("insertOnly",0); // 唯一屬主標識。特殊場景下非常有用,例如根據 App-Client 標識給圖片或視頻打水印。 // type : String // putPolicy.put("endUser",""); // Web 端文件上傳成功後,瀏覽器執行 303 跳轉的 URL。通常用於表單上傳。文件上傳成功後會跳轉到 // <returnUrl>?upload_ret=<queryString>,<queryString>包含 returnBody 內容。 // 如不設置 returnUrl,則直接將 returnUrlnBody 的內容返回給客戶端。 // type : String // putPolicy.put("returnUrl",""); /* *上傳成功後,自定義七牛雲最終返回給上傳端(在指定 returnUrl 時是攜帶在跳轉路徑參數中)的數據。 * 支持魔法變量和自定義變量。returnBody 要求是合法的 JSON 文本。 * 例如 {"key": $(key), "hash": $(etag), "w": $(imageInfo.width), "h": $(imageInfo.height)}。 */ // type : String putPolicy.put("returnBody","{\"key\": $(key), \"hash\": $(etag), \"w\": $(imageInfo.width), \"h\": $(imageInfo.height)}"); /* * 上傳成功後,七牛雲向業務服務器發送 POST 請求的 URL。 * 必須是公網上可以正常進行 POST 請求並能響應 HTTP/1.1 200 OK 的有效 URL。 * 另外,爲了給客戶端有一致的體驗,我們要求 callbackUrl 返回包 Content-Type 爲 "application/json", * 即返回的內容必須是合法的 JSON 文本。出於高可用的考慮,本字段允許設置多個 callbackUrl(用英文符號 ; 分隔), * 在前一個 callbackUrl 請求失敗的時候會依次重試下一個 callbackUrl。 * * 一個典型例子是:http://<ip1>/callback;http://<ip2>/callback,並同時指定下面的 callbackHost 字段。 * 在 callbackUrl 中使用 ip 的好處是減少對 dns 解析的依賴,可改善回調的性能和穩定性。 * 指定 callbackUrl,必須指定 callbackbody,且值不能爲空。 * */ // type : String // putPolicy.put("callbackUrl",""); //上傳成功後,七牛雲向業務服務器發送回調通知時的 Host 值。與 callbackUrl 配合使用,僅當設置了 callbackUrl 時纔有效。 // putPolicy.put("callbackHost",""); /* * * 上傳成功後,七牛雲向業務服務器發送 Content-Type: application/x-www-form-urlencoded 的 POST 請求。 * 業務服務器可以通過直接讀取請求的 query 來獲得該字段,支持魔法變量和自定義變量。 * callbackBody 要求是合法的 url query string。 * 例如key=$(key)&hash=$(etag)&w=$(imageInfo.width)&h=$(imageInfo.height)。 * 如果callbackBodyType指定爲application/json,則callbackBody應爲json格式, * 例如:{"key":"$(key)","hash":"$(etag)","w":"$(imageInfo.width)","h":"$(imageInfo.height)"}。 * */ // type : String putPolicy.put("callbackBody","{\"key\":\"$(key)\",\"hash\":\"$(etag)\",\"w\":\"$(imageInfo.width)\",\"h\":\"$(imageInfo.height)\"}"); //上傳成功後,七牛雲向業務服務器發送回調通知 callbackBody 的 Content-Type。 // 默認爲 application/x-www-form-urlencoded,也可設置爲 application/json。 // type : String putPolicy.put("callbackBodyType","application/json"); /* * 資源上傳成功後觸發執行的預轉持久化處理指令列表。支持魔法變量和自定義變量。 * 每個指令是一個 API 規格字符串,多個指令用;分隔。請參閱persistenOps詳解與示例。 * 同時添加 persistentPipeline 字段,使用專用隊列處理,請參閱persistentPipeline。 * */ // type : String // putPolicy.put("persistentOps",""); /* * 接收持久化處理結果通知的 URL。必須是公網上可以正常進行 POST 請求並能響應 HTTP/1.1 200 OK 的有效 URL。 * 該 URL 獲取的內容和持久化處理狀態查詢的處理結果一致。 * 發送 body 格式是 Content-Type 爲 application/json 的 POST 請求, * 需要按照讀取流的形式讀取請求的body才能獲取 * */ // type : String // putPolicy.put("persistentNotifyUrl",""); //轉碼隊列名。資源上傳成功後,觸發轉碼時指定獨立的隊列進行轉碼。爲空則表示使用公用隊列,處理速度比較慢。建議使用專用隊列。 // type : String // putPolicy.put("persistentPipeline",""); //saveKey的優先級設置。爲 true 時,saveKey不能爲空,會忽略客戶端指定的key,強制使用saveKey進行文件命名。參數不設置時,默認值爲false // type : String // putPolicy.put("forceSaveKey",false); //自定義資源名。支持魔法變量和自定義變量。forceSaveKey 爲false時,這個字段僅當用戶上傳的時候沒有主動指定 key 時起作用; // forceSaveKey 爲true時,將強制按這個字段的格式命名。 // type : String // putPolicy.put("saveKey",""); // 限定上傳文件大小最小值,單位Byte。 // type : int64 // putPolicy.put("fsizeMin",1024); // 限定上傳文件大小最大值,單位Byte。超過限制上傳文件大小的最大值會被判爲上傳失敗,返回 413 狀態碼。 // type : int64 // putPolicy.put("fsizeLimit",2048); /* * 開啓 MimeType 偵測功能。設爲非 0 值,則忽略上傳端傳遞的文件 MimeType 信息,使用七牛服務器偵測內容後的判斷結果。 * 默認設爲 0 值,如上傳端指定了 MimeType 則直接使用該值,否則按如下順序偵測 MimeType 值: * 1. 檢查文件擴展名; * 2. 檢查 Key 擴展名; * 3. 偵測內容。 * 如不能偵測出正確的值,會默認使用 application/octet-stream。 */ // type : int // putPolicy.put("detectMime",1); /* * 限定用戶上傳的文件類型。指定本字段值,七牛服務器會偵測文件內容以判斷 MimeType,再用判斷值跟指定值進行匹配,匹配成功則允許上傳,匹配失敗則返回 403 狀態碼。示例: * image/*表示只允許上傳圖片類型 * image/jpeg;image/png表示只允許上傳jpg和png類型的圖片 * !application/json;text/plain表示禁止上傳json文本和純文本。注意最前面的感嘆號! */ // type : String // putPolicy.put("mimeLimit",""); // 文件存儲類型。0 爲普通存儲(默認),1 爲低頻存儲。 // type : int // putPolicy.put("fileType",0); // 第三步: 生成一個上傳憑證 return auth.uploadToken(publicBucket,null,(System.currentTimeMillis()/1000L+3600),putPolicy); } public static void main(String[] args) { System.out.println(Qiniu.getUploadToken(1, "test")); } }
在這裏面,我將我的數據源配置到了配置文件中,從配置文件中讀取。
這裏再放上一個簡陋的測試頁面:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>客戶端表單上傳文件</title> </head> <body> <!--action中填寫上傳地址,上傳地址參考 https://developer.qiniu.com/kodo/manual/1671/region-endpoint--> <form method="post" action="http://upload.qiniup.com/" enctype="multipart/form-data" accept-charset="UTF-8"> <input name="key" type="hidden" value="6484sdfs54665465"> <!--必須是一個符合相應規格的上傳憑證,否則會返回 401 表示權限認證失敗。--> <input name="token" type="hidden" value="這裏是你生成的上傳憑證"> <!--文件本身。--> <input name="file" type="file" /> <input type="submit" value="上傳文件" /> </form> 下載:<a href="http://pubgwqeja.bkt.clouddn.com/sldsdf">下載</a> </body> </html>
這個是我使用js將後臺傳過來的token和key填入表單的代碼:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>系統設置-廣告設置</title>
<link rel="icon" href="data:;base64,=">
<link rel="stylesheet" type="text/css" href="../../layui/css/layui.css" />
<script src="../../js/jquery-3.4.0.js"></script>
<script src="../../layui/layui.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<form method="post" action="http://upload.qiniup.com/" enctype="multipart/form-data">
<input name="key" id="key" type="hidden">
<input name="token" id="token" type="hidden" >
<input name="file" id="file" type="file" />
<input type="submit" value="上傳文件" />
</form>
<script type="text/javascript">
// 頁面加載的時候使用ajax獲得上傳憑證,並將它賦值給token標籤
jQuery(document).ready(function() {
jQuery.post({
url: "http://localhost:8080/systemSettings/advance/getToken.do",
success: function(result) {
try {
var alldata = eval("(" + result + ")");
var keyNode = document.getElementById("key");
keyNode.value = alldata.key;
var tokenNode = document.getElementById("token");
tokenNode.value = alldata.token;
alert("key:"+alldata.key);
alert("token:"+alldata.token);
} catch (e) {
//TODO handle the exception
console.log("還是錯了");
}
}
})
});
</script>
</body>
</html>
- 下載文件原理
下載文件的原理相比較於上傳文件要簡單很 多,在公開倉庫中的文件,可以直接訪問他的URL進行下載,私有倉庫中的文件則是需要先獲得下載憑證才能進行下載,下載憑證的方法在上面已經有了,就不再進行展示了。
下載文件開發手冊:https://developer.qiniu.com/kodo/manual/1232/download-process