OSS文件上傳
卡片短信模板中使用的圖片、視頻等素材資源可上傳到OSS文件系統(tǒng)保存。
使用須知
本章節(jié)調(diào)用的不是卡片短信API接口,您不需要使用阿里云賬號(hào)進(jìn)行鑒權(quán),直接使用GetOSSInfoForCardTemplate接口返回Signature、Policy、AccessKeyId,通過(guò)HTTP方式即可上傳圖片、視頻素材資源到卡片短信OSS存儲(chǔ)空間。
文件上傳
調(diào)用接口前需配置環(huán)境變量,通過(guò)環(huán)境變量讀取訪問(wèn)憑證。AccessKey ID和AccessKey Secret的環(huán)境變量名:SMS_ACCESS_KEY_ENV 、SMS_ACCESS_KEY_SECRET_ENV。配置詳情請(qǐng)參見(jiàn)配置訪問(wèn)憑證。
OSS文件上傳提供了前端(JS)和后端(JAVA)兩種方式,具體操作請(qǐng)參考文件上傳。
JS端文件上傳
在該頁(yè)面,下載步驟2提供的客戶端源碼(多媒體上傳組件plupload)。
參考JS上傳代碼示例,快速開(kāi)發(fā)一個(gè)OSS文件上傳工具。
accessid = System.getenv("SCA_AK_ENV") host = 'https://example.aliyundoc.com policyBase64 = '****eHBpcmF0aW9uIjoiMjAyMS0wOS0wM1QxNjo0NDoyNC44NTFaIiwiY29uZGl0aW9ucyI6W1siY29udGVudC1sZW5ndGgtcmFuZ2UiLDAsMTA0ODU3NjAwMF0sWyJzdGFydHMtd2l0aCIsIiRrZXkiLCIxMzQ0MzcxLyJdXX0=' signature = 'wQ5XTtBJRpDMcIjXQB8ma06****=' filename = '' key = '1344371/' //以 'StartPath/' 開(kāi)頭 expire = 1630652012 g_object_name = '' g_object_name_type = '' now = timestamp = Date.parse(new Date()) / 1000; function check_object_radio() { var tt = document.getElementsByName('myradio'); for (var i = 0; i < tt.length ; i++ ) { if(tt[i].checked) { g_object_name_type = tt[i].value; break; } } } function random_string(len) { len = len || 32; var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'; var maxPos = chars.length; var pwd = ''; for (i = 0; i < len; i++) { pwd += chars.charAt(Math.floor(Math.random() * maxPos)); } return pwd; } function get_suffix(filename) { pos = filename.lastIndexOf('.') suffix = '' if (pos != -1) { suffix = filename.substring(pos) } return suffix; } function calculate_object_name(filename) { if (g_object_name_type == 'local_name') { g_object_name += "${filename}" } else if (g_object_name_type == 'random_name') { suffix = get_suffix(filename) g_object_name = key + random_string(10) + suffix } return '' } function get_uploaded_object_name(filename) { if (g_object_name_type == 'local_name') { tmp_name = g_object_name tmp_name = tmp_name.replace("${filename}", filename); return tmp_name } else if(g_object_name_type == 'random_name') { return g_object_name } } function set_upload_param(up, filename, ret) { g_object_name = key; if (filename != '') { suffix = get_suffix(filename) calculate_object_name(filename) } new_multipart_params = { 'key' : g_object_name, 'policy': policyBase64, 'OSSAccessKeyId': accessid, 'success_action_status' : '200', //讓服務(wù)端返回200,不然,默認(rèn)會(huì)返回204 'signature': signature, }; up.setOption({ 'url': host, 'multipart_params': new_multipart_params }); up.start(); } var uploader = new plupload.Uploader({ runtimes : 'html5,flash,silverlight,html4', browse_button : 'selectfiles', //multi_selection: false, container: document.getElementById('container'), flash_swf_url : 'lib/plupload-2.1.2/js/Moxie.swf', silverlight_xap_url : 'lib/plupload-2.1.2/js/Moxie.xap', url : 'http://oss.aliyuncs.com', filters: { mime_types : [ //只允許上傳圖片和zip文件 { title : "Image files", extensions : "jpg,gif,png,bmp" }, { title : "Zip files", extensions : "zip,rar" } ], max_file_size : '10mb', //最大只能上傳10MB的文件 prevent_duplicates : true //不允許選取重復(fù)文件 }, init: { PostInit: function() { document.getElementById('ossfile').innerHTML = ''; document.getElementById('postfiles').onclick = function() { set_upload_param(uploader, '', false); return false; }; }, FilesAdded: function(up, files) { plupload.each(files, function(file) { document.getElementById('ossfile').innerHTML += '<div id="' + file.id + '">' + file.name + ' (' + plupload.formatSize(file.size) + ')<b></b>' +'<div class="progress"><div class="progress-bar" style="width: 0%"></div></div>' +'</div>'; }); }, BeforeUpload: function(up, file) { check_object_radio(); set_upload_param(up, file.name, true); }, UploadProgress: function(up, file) { var d = document.getElementById(file.id); d.getElementsByTagName('b')[0].innerHTML = '<span>' + file.percent + "%</span>"; var prog = d.getElementsByTagName('div')[0]; var progBar = prog.getElementsByTagName('div')[0] progBar.style.width= 2*file.percent+'px'; progBar.setAttribute('aria-valuenow', file.percent); }, FileUploaded: function(up, file, info) { if (info.status == 200) { document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = 'upload to oss success, object name:' + get_uploaded_object_name(file.name) + ' 回調(diào)服務(wù)器返回的內(nèi)容是:' + info.response; } else if (info.status == 203) { document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = '上傳到OSS成功,但是oss訪問(wèn)用戶設(shè)置的上傳回調(diào)服務(wù)器失敗,失敗原因是:' + info.response; } else { document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = info.response; } }, Error: function(up, err) { if (err.code == -600) { document.getElementById('console').appendChild(document.createTextNode("\n選擇的文件太大了,可以根據(jù)應(yīng)用情況,在upload.js 設(shè)置一下上傳的最大大小")); } else if (err.code == -601) { document.getElementById('console').appendChild(document.createTextNode("\n選擇的文件后綴不對(duì),可以根據(jù)應(yīng)用情況,在upload.js進(jìn)行設(shè)置可允許的上傳文件類(lèi)型")); } else if (err.code == -602) { document.getElementById('console').appendChild(document.createTextNode("\n這個(gè)文件已經(jīng)上傳過(guò)一遍了")); } else { document.getElementById('console').appendChild(document.createTextNode("\nError xml:" + err.response)); } } } }); uploader.init();
修改JS上傳代碼實(shí)例中OSS參數(shù)的設(shè)置,數(shù)據(jù)來(lái)源于獲取OSS上傳信息GetOSSInfoForCardTemplate接口的調(diào)用結(jié)果,對(duì)應(yīng)關(guān)系詳見(jiàn)下表。
JS參數(shù)
對(duì)應(yīng)OSS結(jié)果數(shù)據(jù)
示例
accessid
Data.AccessKeyId
System.getenv("SCA_AK_ENV")
host
Data.Host
https://example.aliyundoc.com
policyBase64
Data.Policy
eyJleHBpcmF0aW9uIjoiMjAyMS0wOS0wM1QxNjo0NDoyNC44NTFaIiwiY29uZGl0aW9ucyI6W1siY29ud****
signature
Data.Signature
wQ5XTtBJRpDMcIjXQB8ma****
key
Data.StartPath+/
以StartPath開(kāi)頭后面添加/
示例:1344371/
上傳文件,提交資源到OSS并獲得返回結(jié)果。
組裝并獲得OSSKey,組裝規(guī)則:
oss://bucket/startPath/filenameBucket = GetOSSInfoForCardTemplate接口返回的Data.Bucket (取值alicom-cardsms-resources)startPath/filename
可以從上一步的返回結(jié)果object name后面的文件地址截取,也可以自行組裝。
OSSKey示例:oss://alicom-cardsms-resources/1344371****/111222.jpg
JAVA端上傳文件
JAVA OSS上傳文件示例:
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.3</version> </dependency>
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpmime</artifactId> <version>4.5.3</version> </dependency>
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.0</version> </dependency>
import org.apache.commons.codec.binary.Base64; import javax.activation.MimetypesFileTypeMap; import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; public class OSSSample { private String accessKeyId = System.getenv("SCA_AK_ENV") private String signature = "sQtVRyeiajpq+4f826hx00xv/zg="; private String policy = "****eHBpcmF0aW9uIjoiMjAyMS0xMi0wNlQwODowMTowMC40NjJaIiwiY29uZGl0aW9ucyI6W1siY29udGVudC1sZW5ndGgtcmFuZ2UiLDAsMTA0ODU3NjAwMF0sWyJzdGFydHMtd2l0aCIsIiRrZXkiLCIxMzQ0MzcxLyJdXX0="; private String objectName = "1344371/x1.txt"; //"yourAliyunId/" 開(kāi)頭 ; private String bucketName = "alicom-cardsms-resources"; private String endpoint = "https://example.aliyundoc.com"; private String localFilePath = "/Users/xxx/x.txt"; /** * 表單上傳。 * * @throws Exception */ private void PostObject() throws Exception { // 設(shè)置表單Map。 Map<String, String> formFields = new LinkedHashMap<String, String>(); // 設(shè)置文件名稱。 formFields.put("key", this.objectName); // 設(shè)置Content-Disposition。 formFields.put("Content-Disposition", "attachment;filename=" + localFilePath); // 如需回調(diào),在表單Map中設(shè)置回調(diào)參數(shù)。 // setCallBack(formFields, callback); // 設(shè)置OSSAccessKeyId。 formFields.put("OSSAccessKeyId", accessKeyId); // 設(shè)置policy。 formFields.put("policy", policy); // 設(shè)置簽名。 formFields.put("Signature", signature); String ret = formUpload(endpoint, formFields, localFilePath); System.out.println("Post Object [" + this.objectName + "] to bucket [" + bucketName + "]"); System.out.println("post reponse:" + ret); } private static String formUpload(String urlStr, Map<String, String> formFields, String localFile) throws Exception { String res = ""; HttpURLConnection conn = null; String boundary = "9431149156168"; try { URL url = new URL(urlStr); conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(5000); conn.setReadTimeout(30000); conn.setDoOutput(true); conn.setDoInput(true); conn.setRequestMethod("POST"); conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.*.*)"); // 如需設(shè)置MD5值。MD5值由整個(gè)body計(jì)算得出。 // conn.setRequestProperty("Content-MD5", "<yourContentMD5>"); conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); OutputStream out = new DataOutputStream(conn.getOutputStream()); // 遍歷讀取表單Map中的數(shù)據(jù),將數(shù)據(jù)寫(xiě)入到輸出流中。 if (formFields != null) { StringBuffer strBuf = new StringBuffer(); Iterator<Map.Entry<String, String>> iter = formFields.entrySet() .iterator(); int i = 0; while (iter.hasNext()) { Map.Entry<String, String> entry = iter.next(); String inputName = entry.getKey(); String inputValue = entry.getValue(); if (inputValue == null) { continue; } if (i == 0) { strBuf.append("--").append(boundary).append("\r\n"); strBuf.append("Content-Disposition: form-data; name=\"" + inputName + "\"\r\n\r\n"); strBuf.append(inputValue); } else { strBuf.append("\r\n").append("--").append(boundary).append("\r\n"); strBuf.append("Content-Disposition: form-data; name=\"" + inputName + "\"\r\n\r\n"); strBuf.append(inputValue); } i++; } out.write(strBuf.toString().getBytes()); } // 讀取文件信息,將要上傳的文件寫(xiě)入到輸出流中。 File file = new File(localFile); String filename = file.getName(); String contentType = new MimetypesFileTypeMap().getContentType(file); if (contentType == null || contentType.equals("")) { contentType = "application/octet-stream"; } StringBuffer strBuf = new StringBuffer(); strBuf.append("\r\n").append("--").append(boundary) .append("\r\n"); strBuf.append("Content-Disposition: form-data; name=\"file\"; " + "filename=\"" + filename + "\"\r\n"); strBuf.append("Content-Type: " + contentType + "\r\n\r\n"); out.write(strBuf.toString().getBytes()); DataInputStream in = new DataInputStream(new FileInputStream(file)); int bytes = 0; byte[] bufferOut = new byte[1024]; while ((bytes = in.read(bufferOut)) != -1) { out.write(bufferOut, 0, bytes); } in.close(); byte[] endData = ("\r\n--" + boundary + "--\r\n").getBytes(); out.write(endData); out.flush(); out.close(); // 讀取返回?cái)?shù)據(jù)。 strBuf = new StringBuffer(); BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); String line = null; while ((line = reader.readLine()) != null) { strBuf.append(line).append("\n"); } res = strBuf.toString(); reader.close(); reader = null; } catch (Exception e) { System.err.println("Send post request exception: " + e); throw e; } finally { if (conn != null) { conn.disconnect(); conn = null; } } return res; } public static void main(String[] args) throws Exception { OSSSample ossPostObject = new OSSSample(); ossPostObject.PostObject(); } }
修改OSS參數(shù)配置,數(shù)據(jù)來(lái)源于獲取OSS上傳信息GetOSSInfoForCardTemplate接口的調(diào)用結(jié)果,對(duì)應(yīng)關(guān)系詳見(jiàn)下表。
Java參數(shù)
對(duì)應(yīng)OSS結(jié)果數(shù)據(jù)
示例
accessKeyId
Data.AccessKeyId
System.getenv("SCA_AK_ENV")
url
Data.Host
https://example.aliyundoc.com
policy
Data.Policy
eyJleHBpcmF0aW9uIjoiMjAyMS0wOS0xNlQwMzoyMjo1My44NjJaIiwiY29uZGl0aW9ucyI6W1siY29udGVudC1sZW5ndGgtcmFuZ2UiLDAsMTA0ODU3NjAwMF0sWyJzdGFydHMtd2l0aCIsIiRrZXkiLCIxMzQ0Mz****=
signature
Data.Signature
hK1BMsXZqCJvmnsZ98yG1b5****=
key
Data.StartPath+/
以StartPath開(kāi)頭后面添加/
示例:1344371/
bucket
Data.Bucket
alicom-cardsms-resources并非必要