Setelah objek diunggah, Object Storage Service (OSS) dapat mengirim permintaan callback ke server aplikasi. Untuk mengimplementasikan callback, cukup kirim permintaan yang berisi parameter callback terkait ke OSS.
Catatan penggunaan
Topik ini menggunakan titik akhir publik wilayah China (Hangzhou). Untuk mengakses OSS dari layanan Alibaba Cloud lainnya dalam wilayah yang sama, gunakan titik akhir internal. Untuk detail wilayah dan titik akhir yang didukung, lihat Wilayah dan titik akhir.
Kredensial akses pada topik ini diperoleh dari variabel lingkungan. Untuk informasi lebih lanjut tentang cara mengonfigurasi kredensial akses, lihat Konfigurasi kredensial akses.
Instans OSSClient pada topik ini dibuat menggunakan titik akhir OSS. Jika Anda ingin membuat instans OSSClient menggunakan nama domain kustom atau Security Token Service (STS), lihat Contoh konfigurasi untuk skenario umum.
Kode contoh
Konfigurasikan callback unggahan untuk tugas unggahan simple
import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.Callback;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import java.io.ByteArrayInputStream;
public class Demo {
public static void main(String[] args) throws Exception{
// Tentukan titik akhir wilayah. Pada contoh ini, titik akhir wilayah China (Hangzhou) digunakan.
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// Peroleh kredensial akses dari variabel lingkungan. Sebelum menjalankan kode contoh, pastikan variabel lingkungan OSS_ACCESS_KEY_ID dan OSS_ACCESS_KEY_SECRET telah dikonfigurasi.
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// Tentukan nama bucket. Contoh: examplebucket.
String bucketName = "examplebucket";
// Tentukan path lengkap objek. Contoh: exampledir/exampleobject.txt. Jangan sertakan nama bucket dalam path lengkap.
String objectName = "exampledir/exampleobject.txt";
// Tentukan alamat server tempat permintaan callback dikirim. Contoh: https://example.com:23450.
String callbackUrl = "yourCallbackServerUrl";
// Tentukan wilayah tempat bucket berada. Misalnya, jika bucket berada di wilayah China (Hangzhou), atur wilayah menjadi cn-hangzhou.
String region = "cn-hangzhou";
// Buat instans OSSClient.
// Panggil metode shutdown untuk melepaskan resource terkait saat OSSClient tidak lagi digunakan.
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
OSS ossClient = OSSClientBuilder.create()
.endpoint(endpoint)
.credentialsProvider(credentialsProvider)
.clientConfiguration(clientBuilderConfiguration)
.region(region)
.build();
try {
String content = "Hello OSS";
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName,new ByteArrayInputStream(content.getBytes()));
// Konfigurasikan parameter callback unggahan.
Callback callback = new Callback();
callback.setCallbackUrl(callbackUrl);
// (Opsional) Tentukan field CallbackHost dalam header permintaan callback.
// callback.setCallbackHost("yourCallbackHost");
// Atur badan permintaan callback dalam format JSON dan definisikan variabel placeholder di dalamnya.
callback.setCalbackBodyType(Callback.CalbackBodyType.JSON);
callback.setCallbackBody("{\\\"bucket\\\":${bucket},\\\"object\\\":${object},\\\"mimeType\\\":${mimeType},\\\"size\\\":${size},\\\"my_var1\\\":${x:var1},\\\"my_var2\\\":${x:var2}}");
// Konfigurasikan parameter kustom untuk permintaan callback. Setiap parameter kustom terdiri dari kunci dan nilai. Kunci harus diawali dengan x:.
callback.addCallbackVar("x:var1", "value1");
callback.addCallbackVar("x:var2", "value2");
putObjectRequest.setCallback(callback);
// Lakukan operasi unggah.
PutObjectResult putObjectResult = ossClient.putObject(putObjectRequest);
// Baca konten pesan yang dikembalikan dari callback unggahan.
byte[] buffer = new byte[1024];
putObjectResult.getResponse().getContent().read(buffer);
// Anda harus menutup aliran yang diperoleh setelah data dibaca. Jika tidak, kebocoran koneksi dapat terjadi. Akibatnya, tidak ada koneksi yang tersedia dan terjadi exception.
putObjectResult.getResponse().getContent().close();
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (Throwable ce) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}Konfigurasikan callback unggahan untuk tugas unggahan multipart
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.internal.Mimetypes;
import com.aliyun.oss.model.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
public class Demo {
public static void main(String[] args) throws Exception {
// Pada contoh ini, titik akhir wilayah China (Hangzhou) digunakan. Tentukan titik akhir aktual Anda.
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// Peroleh kredensial akses dari variabel lingkungan. Sebelum menjalankan kode contoh, pastikan variabel lingkungan OSS_ACCESS_KEY_ID dan OSS_ACCESS_KEY_SECRET telah dikonfigurasi.
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// Tentukan nama bucket. Contoh: examplebucket.
String bucketName = "examplebucket";
// Tentukan path lengkap objek. Contoh: exampledir/exampleobject.txt. Jangan sertakan nama bucket dalam path lengkap.
String objectName = "exampledir/exampleobject.txt";
// Tentukan path lengkap file lokal yang ingin Anda unggah.
String filePath = "D:\\localpath\\examplefile.txt";
// Tentukan wilayah tempat bucket berada. Misalnya, jika bucket berada di wilayah China (Hangzhou), atur wilayah menjadi cn-hangzhou.
String region = "cn-hangzhou";
// Tentukan alamat server tempat permintaan callback dikirim. Contoh: https://example.com:23450.
String callbackUrl = "https://example.com:23450";
// Buat instans OSSClient.
// Panggil metode shutdown untuk melepaskan resource terkait saat OSSClient tidak lagi digunakan.
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
OSS ossClient = OSSClientBuilder.create()
.endpoint(endpoint)
.credentialsProvider(credentialsProvider)
.clientConfiguration(clientBuilderConfiguration)
.region(region)
.build();
try {
// Buat objek InitiateMultipartUploadRequest.
InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(bucketName, objectName);
// Konfigurasikan metadata objek dan ambil Content-Type objek.
ObjectMetadata metadata = new ObjectMetadata();
if (metadata.getContentType() == null) {
metadata.setContentType(Mimetypes.getInstance().getMimetype(new File(filePath), objectName));
}
System.out.println("Content-Type: " + metadata.getContentType());
// Sertakan metadata dalam permintaan unggah.
request.setObjectMetadata(metadata);
// Inisialisasi tugas unggahan multipart.
InitiateMultipartUploadResult upresult = ossClient.initiateMultipartUpload(request);
// Peroleh ID unggah.
String uploadId = upresult.getUploadId();
// partETags adalah kumpulan PartETags. PartETag suatu bagian terdiri dari nomor bagian dan nilai ETag bagian tersebut.
List<PartETag> partETags = new ArrayList<PartETag>();
// Tentukan ukuran setiap bagian, yang digunakan untuk menghitung jumlah bagian objek. Satuan: byte.
Setiap bagian dapat berukuran 100 KB hingga 5 GB. Ukuran bagian terakhir dapat kurang dari 100 KB.
// Atur ukuran bagian dalam byte. Pada contoh ini, ukuran bagian diatur menjadi 1 MB.
final long partSize = 1 * 1024 * 1024L;
// Hitung jumlah bagian berdasarkan ukuran data yang diunggah. Pada kode contoh berikut, file lokal digunakan sebagai contoh untuk menjelaskan cara menggunakan metode File.length() guna memperoleh ukuran data yang diunggah.
final File sampleFile = new File(filePath);
long fileLength = sampleFile.length();
int partCount = (int) (fileLength / partSize);
if (fileLength % partSize != 0) {
partCount++;
}
// Unggah semua bagian objek.
for (int i = 0; i < partCount; i++) {
long startPos = i * partSize;
long curPartSize = (i + 1 == partCount) ? (fileLength - startPos) : partSize;
UploadPartRequest uploadPartRequest = new UploadPartRequest();
uploadPartRequest.setBucketName(bucketName);
uploadPartRequest.setKey(objectName);
uploadPartRequest.setUploadId(uploadId);
// Tentukan aliran input untuk tugas unggahan multipart.
// Pada kode contoh berikut, file lokal digunakan sebagai contoh untuk menjelaskan cara membuat objek FileInputStream dan menggunakan metode InputStream.skip() untuk melewati data tertentu.
InputStream instream = new FileInputStream(sampleFile);
instream.skip(startPos);
uploadPartRequest.setInputStream(instream);
// Tentukan ukuran yang tersedia untuk setiap bagian.
uploadPartRequest.setPartSize(curPartSize);
// Tentukan nomor bagian. Setiap bagian memiliki nomor bagian yang berkisar antara 1 hingga 10.000. Jika nomor bagian yang Anda tentukan berada di luar rentang tersebut, kode kesalahan InvalidArgument akan dikembalikan.
uploadPartRequest.setPartNumber(i + 1);
// Bagian tidak harus diunggah secara berurutan dan dapat diunggah dari klien OSS yang berbeda. OSS mengurutkan bagian berdasarkan nomor bagian dan menggabungkan bagian menjadi satu objek utuh.
UploadPartResult uploadPartResult = ossClient.uploadPart(uploadPartRequest);
// Setelah bagian diunggah, OSS mengembalikan hasil yang berisi PartETag. PartETag disimpan dalam partETags.
partETags.add(uploadPartResult.getPartETag());
// Nonaktifkan aliran input.
instream.close();
}
// Buat objek CompleteMultipartUploadRequest.
// Saat Anda memanggil operasi CompleteMultipartUpload, Anda harus menyediakan semua PartETags yang valid. Setelah OSS menerima PartETags, OSS memverifikasi semua bagian satu per satu. Setelah semua bagian diverifikasi, OSS menggabungkan bagian-bagian tersebut menjadi satu objek utuh.
CompleteMultipartUploadRequest completeMultipartUploadRequest =
new CompleteMultipartUploadRequest(bucketName, objectName, uploadId, partETags);
// Tentukan parameter callback unggahan.
Callback callback = new Callback();
callback.setCallbackUrl(callbackUrl);
// (Opsional) Tentukan field CallbackHost dalam header permintaan callback.
// callback.setCallbackHost("yourCallbackHost");
// Atur badan permintaan callback dalam format JSON dan definisikan variabel placeholder di dalamnya.
callback.setCalbackBodyType(Callback.CalbackBodyType.JSON);
callback.setCallbackBody("{\\\"bucket\\\":${bucket},\\\"object\\\":${object},\\\"mimeType\\\":${mimeType},\\\"size\\\":${size},\\\"my_var1\\\":${x:var1},\\\"my_var2\\\":${x:var2}}");
// Konfigurasikan parameter kustom untuk permintaan callback. Setiap parameter kustom terdiri dari kunci dan nilai. Kunci harus diawali dengan x:.
callback.addCallbackVar("x:var1", "value1");
callback.addCallbackVar("x:var2", "value2");
completeMultipartUploadRequest.setCallback(callback);
// Selesaikan tugas unggahan multipart.
CompleteMultipartUploadResult completeMultipartUploadResult = ossClient.completeMultipartUpload(completeMultipartUploadRequest);
System.out.println("Upload successful,ETag:" + completeMultipartUploadResult.getETag());
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("Caught a ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}Unggah objek menggunakan form dan konfigurasikan pengaturan callback unggahan
import com.aliyun.oss.ClientException;
import com.aliyun.oss.common.auth.ServiceSignature;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.common.utils.StringUtils;
import com.aliyun.oss.internal.OSSUtils;
import com.aliyun.oss.model.Callback;
import org.apache.commons.codec.binary.Base64;
import javax.activation.MimetypesFileTypeMap;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
public class PostObjectCallbackV4Demo {
// Tentukan path lengkap file lokal yang ingin Anda unggah.
private static final String localFilePath = "D:\\localpath\\examplefile.txt";
// Pada contoh ini, titik akhir wilayah China (Hangzhou) digunakan. Tentukan titik akhir aktual Anda.
private static final String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
// Pasangan AccessKey akun Alibaba Cloud memiliki izin atas semua operasi API. Menggunakan kredensial ini untuk melakukan operasi di OSS menimbulkan risiko keamanan yang signifikan. Kami menyarankan agar Anda memanggil operasi API atau melakukan O&M rutin sebagai Pengguna Resource Access Management (RAM). Untuk membuat pengguna RAM, login ke Konsol RAM.
private static final String accessKeyId = System.getenv("OSS_ACCESS_KEY_ID");
private static final String accessKeySecret = System.getenv("OSS_ACCESS_KEY_SECRET");
// Tentukan nama bucket. Contoh: examplebucket.
private static final String bucketName = "examplebucket";
// Tentukan path lengkap objek. Contoh: exampledir/exampleobject.txt. Jangan sertakan nama bucket dalam path lengkap.
private static final String objectName = "exampledir/exampleobject.txt";
// Tentukan URL server tempat Anda ingin mengirim permintaan callback. Contoh: http://oss-demo.oss-cn-hangzhou.aliyuncs.com:23450 atau http://127.0.0.1:9090.
private static final String callbackServerUrl = "http://oss-demo.oss-cn-hangzhou.aliyuncs.com:23450";
// Tentukan header Host dalam permintaan callback. Contoh: oss-cn-hangzhou.aliyuncs.com.
private static final String callbackServerHost = "";
// Tentukan wilayah tempat bucket berada. Misalnya, jika bucket berada di wilayah China (Hangzhou), atur wilayah menjadi cn-hangzhou.
private static final String region = "cn-hangzhou";
private static Date requestDateTime = new Date();
/**
* Lakukan unggahan form.
* @throws Exception
*/
private void PostObject() throws Exception {
// Tambahkan nama bucket ke URL. Format URL adalah http://yourBucketName.oss-cn-hangzhou.aliyuncs.com.
String urlStr = endpoint.replace("http://", "http://" + bucketName+ ".");
// Bangun parameter form.
Map<String, String> formFields = new LinkedHashMap<String, String>();
formFields.put("key", objectName);
formFields.put("Content-Disposition", "attachment;filename="
+ localFilePath);
// Tentukan parameter callback.
Callback callback = new Callback();
// Tentukan URL server tempat Anda ingin mengirim permintaan callback. Contoh: http://oss-demo.oss-cn-hangzhou.aliyuncs.com:23450 atau http://127.0.0.1:9090.
callback.setCallbackUrl(callbackServerUrl);
// Tentukan header Host dalam permintaan callback. Contoh: oss-cn-hangzhou.aliyuncs.com.
callback.setCallbackHost(callbackServerHost);
// Atur badan permintaan callback dalam format JSON dan definisikan variabel placeholder di dalamnya.
callback.setCalbackBodyType(Callback.CalbackBodyType.JSON);
callback.setCallbackBody("{\\\"bucket\\\":${bucket},\\\"object\\\":${object},\\\"mimeType\\\":${mimeType},\\\"size\\\":${size},\\\"my_var1\\\":${x:var1},\\\"my_var2\\\":${x:var2}}");
// Tentukan parameter kustom dalam permintaan callback. Setiap parameter kustom terdiri dari pasangan kunci-nilai. Kunci harus diawali dengan x: dan ditulis dalam huruf kecil.
callback.addCallbackVar("x:var1", "value1");
callback.addCallbackVar("x:var2", "value2");
// Tentukan parameter callback dalam Map untuk form.
setCallBack(formFields, callback);
// Tentukan OSSAccessKeyId.
formFields.put("OSSAccessKeyId", accessKeyId);
String policy = "{\"expiration\": \"2120-01-01T12:00:00.000Z\",\"conditions\": [" +
" {\"x-oss-signature-version\": \"OSS4-HMAC-SHA256\"},\n" +
" {\"x-oss-credential\": \""+accessKeyId+"/"+getDate()+"/"+region+"/oss/aliyun_v4_request\"},\n" +
" {\"x-oss-date\": \""+getDateTime()+"\"},\n" +
" [\"content-length-range\", 0, 104857600]" +
"]}";
String encodePolicy = new String(Base64.encodeBase64(policy.getBytes()));
// Atur kebijakan.
formFields.put("policy", encodePolicy);
System.out.println("policy:" + policy);
// Hasilkan signature.
formFields.put("x-oss-signature-version", "OSS4-HMAC-SHA256");
formFields.put("x-oss-credential", accessKeyId+"/"+getDate()+"/"+region+"/oss/aliyun_v4_request");
formFields.put("x-oss-date", getDateTime());
String stringToSign = new String(Base64.encodeBase64(policy.getBytes()));
System.out.println("stringToSign:" + stringToSign);
byte[] signingKey = buildSigningKey();
String signature = buildSignature(signingKey, stringToSign);
formFields.put("x-oss-signature", signature);
System.out.println("Signature:" + signature);
// Lakukan operasi unggah.
String ret = formUpload(urlStr, formFields);
System.out.println("Post Object [" + objectName + "] to bucket [" + bucketName + "]");
System.out.println("post reponse:" + ret);
}
private static String formUpload(String urlStr, Map<String, String> formFields)
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.2.6)");
conn.setRequestProperty("Content-Type",
"multipart/form-data; boundary=" + boundary);
// Proses field form.
OutputStream out = new DataOutputStream(conn.getOutputStream());
// Baca semua data Map untuk form secara rekursif dan tulis data ke aliran output.
if (formFields != null) {
StringBuilder strBuf = new StringBuilder();
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=\"").append(inputName).append("\"\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());
}
// Baca file dan tulis ke aliran output.
File file = new File(localFilePath);
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();
// Baca data yang dikembalikan.
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 (ClientException e) {
System.err.println("Send post request exception: " + e);
System.err.println(e.getErrorCode()+" msg="+e.getMessage());
throw e;
} finally {
if (conn != null) {
conn.disconnect();
conn = null;
}
}
return res;
}
private static void setCallBack(Map<String, String> formFields, Callback callback) {
if (callback != null) {
String jsonCb = OSSUtils.jsonizeCallback(callback);
String base64Cb = BinaryUtil.toBase64String(jsonCb.getBytes());
formFields.put("callback", base64Cb);
if (callback.hasCallbackVar()) {
Map<String, String> varMap = callback.getCallbackVar();
for (Map.Entry<String, String> entry : varMap.entrySet()) {
formFields.put(entry.getKey(), entry.getValue());
}
}
}
}
private static String getDateTime() {
return getIso8601DateTimeFormat().format(requestDateTime);
}
private static DateFormat getIso8601DateTimeFormat() {
SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'", Locale.US);
df.setTimeZone(new SimpleTimeZone(0, "GMT"));
return df;
}
private static DateFormat getIso8601DateFormat() {
SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd", Locale.US);
df.setTimeZone(new SimpleTimeZone(0, "GMT"));
return df;
}
private static String getDate() {
return getIso8601DateFormat().format(requestDateTime);
}
private String buildSignature(byte[] signingKey, String stringToSign) {
byte[] result = ServiceSignature.create("HmacSHA256").computeHash(signingKey, stringToSign.getBytes(StringUtils.UTF8));
return BinaryUtil.toHex(result);
}
private byte[] buildSigningKey() {
ServiceSignature signature = ServiceSignature.create("HmacSHA256");
byte[] signingSecret = ("aliyun_v4" + accessKeySecret).getBytes(StringUtils.UTF8);
byte[] signingDate = signature.computeHash(signingSecret, getDate().getBytes(StringUtils.UTF8));
byte[] signingRegion = signature.computeHash(signingDate, region.getBytes(StringUtils.UTF8));
byte[] signingService = signature.computeHash(signingRegion, "oss".getBytes(StringUtils.UTF8));
/*System.out.println("signingSecret:\n" + BinaryUtil.toHex(signingSecret));
System.out.println("signingDate:\n" + BinaryUtil.toHex(signingDate));
System.out.println("signingRegion:\n" + BinaryUtil.toHex(signingRegion));
System.out.println("signingService:\n" + BinaryUtil.toHex(signingService));*/
return signature.computeHash(signingService, "aliyun_v4_request".getBytes(StringUtils.UTF8));
}
public static void main(String[] args) throws Exception {
PostObjectCallbackV4Demo ossPostObject = new PostObjectCallbackV4Demo();
ossPostObject.PostObject();
}
}
Konfigurasikan callback unggahan untuk tugas unggahan yang dapat dilanjutkan
package Callback;
import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSS;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.internal.Mimetypes;
import com.aliyun.oss.model.*;
import java.io.File;
public class Demo {
public static void main(String[] args) throws Exception {
// Pada contoh ini, titik akhir wilayah China (Hangzhou) digunakan. Tentukan titik akhir aktual Anda.
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// Peroleh kredensial akses dari variabel lingkungan. Sebelum menjalankan kode contoh, pastikan variabel lingkungan OSS_ACCESS_KEY_ID dan OSS_ACCESS_KEY_SECRET telah dikonfigurasi.
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// Tentukan nama bucket. Contoh: examplebucket.
String bucketName = "examplebucket";
// Tentukan path lengkap objek. Contoh: exampledir/exampleobject.txt. Jangan sertakan nama bucket dalam path lengkap.
String objectName = "exampledir/exampleobject.txt";
// Tentukan path lengkap file lokal. Contoh: D:\\localpath\\examplefile.txt.
String filePath = "D:\\localpath\\examplefile.txt";
// Tentukan wilayah tempat bucket berada. Misalnya, jika bucket berada di wilayah China (Hangzhou), atur wilayah menjadi cn-hangzhou.
String region = "cn-hangzhou";
// Tentukan alamat server tempat permintaan callback dikirim. Contoh: https://example.com:23450.
String callbackUrl = "http://example.com:23450/callback";
// Buat instans OSSClient.
// Panggil metode shutdown untuk melepaskan resource terkait saat OSSClient tidak lagi digunakan.
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
OSS ossClient = OSSClientBuilder.create()
.endpoint(endpoint)
.credentialsProvider(credentialsProvider)
.clientConfiguration(clientBuilderConfiguration)
.region(region)
.build();
try {
// Konfigurasikan metadata objek dan ambil Content-Type objek.
ObjectMetadata metadata = new ObjectMetadata();
if (metadata.getContentType() == null) {
metadata.setContentType(Mimetypes.getInstance().getMimetype(new File(filePath), objectName));
}
System.out.println("Content-Type: " + metadata.getContentType());
// Konfigurasikan beberapa parameter menggunakan UploadFileRequest.
// Tentukan nama bucket seperti examplebucket dan path lengkap objek seperti exampledir/exampleobject.txt. Jangan sertakan nama bucket dalam path lengkap.
UploadFileRequest uploadFileRequest = new UploadFileRequest(bucketName,objectName);
// Konfigurasikan parameter tunggal menggunakan UploadFileRequest.
// Tentukan path lengkap file lokal. Contoh: D:\\localpath\\examplefile.txt. Secara default, jika Anda tidak menentukan path file lokal, file diunggah dari path lokal proyek tempat program contoh berada.
uploadFileRequest.setUploadFile(filePath);
// Tentukan jumlah thread konkuren untuk tugas unggah. Nilai default: 1.
uploadFileRequest.setTaskNum(5);
// Tentukan ukuran bagian. Satuan: byte. Nilai valid: 100 KB hingga 5 GB. Nilai default: 100 KB.
uploadFileRequest.setPartSize(1 * 1024 * 1024);
// Tentukan apakah akan mengaktifkan unggahan yang dapat dilanjutkan. Secara default, unggahan yang dapat dilanjutkan dinonaktifkan.
uploadFileRequest.setEnableCheckpoint(true);
// Tentukan file titik pemeriksaan yang mencatat progres unggahan setiap bagian. File ini menyimpan informasi tentang progres unggahan. Jika suatu bagian gagal diunggah, tugas dapat dilanjutkan berdasarkan progres yang dicatat dalam file titik pemeriksaan. Setelah objek diunggah, file titik pemeriksaan dihapus.
// Secara default, jika Anda tidak menentukan parameter ini, file titik pemeriksaan berada dalam direktori yang sama dengan objek yang ingin Anda unggah. Direktori tersebut bernama ${uploadFile}.ucp.
uploadFileRequest.setCheckpointFile("yourCheckpointFile");
// Konfigurasikan metadata objek.
uploadFileRequest.setObjectMetadata(metadata);
// Konfigurasikan parameter callback unggahan.
Callback callback = new Callback();
callback.setCallbackUrl(callbackUrl);
// (Opsional) Tentukan field CallbackHost dalam header permintaan callback.
// callback.setCallbackHost("yourCallbackHost");
// Atur badan permintaan callback dalam format JSON dan definisikan variabel placeholder di dalamnya.
callback.setCalbackBodyType(Callback.CalbackBodyType.JSON);
callback.setCallbackBody("{\\\"bucket\\\":${bucket},\\\"object\\\":${object},\\\"mimeType\\\":${mimeType},\\\"size\\\":${size},\\\"my_var1\\\":${x:var1},\\\"my_var2\\\":${x:var2}}");
// Konfigurasikan parameter kustom untuk permintaan callback. Setiap parameter kustom terdiri dari kunci dan nilai. Kunci harus diawali dengan x:.
callback.addCallbackVar("x:var1", "value1");
callback.addCallbackVar("x:var2", "value2");
// Konfigurasikan callback unggahan. Jenis parameternya adalah Callback.
uploadFileRequest.setCallback(callback);
// Mulai unggahan yang dapat dilanjutkan.
ossClient.uploadFile(uploadFileRequest);
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (Throwable ce) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
// Matikan instans OSSClient.
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}
Gunakan URL yang ditandatangani untuk mengunggah objek dan atur parameter callback unggahan
Hasilkan URL yang ditandatangani yang mencakup parameter callback unggahan untuk mengaktifkan unggahan menggunakan permintaan HTTP PUT.
import com.aliyun.oss.*; import com.aliyun.oss.common.auth.CredentialsProviderFactory; import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider; import com.aliyun.oss.common.comm.SignVersion; import com.aliyun.oss.internal.OSSHeaders; import com.aliyun.oss.model.GeneratePresignedUrlRequest; import java.net.URL; import java.text.SimpleDateFormat; import java.util.*; public class OssPresignExample { public static void main(String[] args) throws Throwable { // Pada contoh ini, titik akhir wilayah China (Hangzhou) digunakan. Tentukan titik akhir aktual Anda. String endpoint = "https://oss-cn-hangzhou.aliyuncs.com"; // Peroleh kredensial akses dari variabel lingkungan. Sebelum menjalankan kode contoh, pastikan variabel lingkungan OSS_ACCESS_KEY_ID dan OSS_ACCESS_KEY_SECRET telah dikonfigurasi. EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // Tentukan nama bucket. Contoh: examplebucket. String bucketName = "examplebucket"; // Tentukan path lengkap objek. Contoh: exampleobject.txt. Jangan sertakan nama bucket dalam path lengkap. String objectName = "exampleobject.txt"; // Tentukan wilayah tempat bucket berada. Misalnya, jika bucket berada di wilayah China (Hangzhou), atur wilayah menjadi cn-hangzhou. String region = "cn-hangzhou"; // Buat instans OSSClient. // Panggil metode shutdown untuk melepaskan resource terkait saat OSSClient tidak lagi digunakan. ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration(); clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); OSS ossClient = OSSClientBuilder.create() .endpoint(endpoint) .credentialsProvider(credentialsProvider) .clientConfiguration(clientBuilderConfiguration) .region(region) .build(); URL signedUrl = null; try { // Bangun parameter callback. String callbackUrl = "http://www.example.com/callback"; String callbackBody = "{\"callbackUrl\":\"" + callbackUrl + "\",\"callbackBody\":\"bucket=${bucket}&object=${object}&my_var_1=${x:var1}&my_var_2=${x:var2}\"}"; String callbackBase64 = Base64.getEncoder().encodeToString(callbackBody.getBytes()); String callbackVarJson = "{\"x:var1\":\"value1\",\"x:var2\":\"value2\"}"; String callbackVarBase64 = Base64.getEncoder().encodeToString(callbackVarJson.getBytes()); // Tentukan header permintaan. Map<String, String> headers = new HashMap<String, String>(); // Tentukan parameter callback. headers.put(OSSHeaders.OSS_HEADER_CALLBACK, callbackBase64); // Tentukan parameter callback-var. headers.put(OSSHeaders.OSS_HEADER_CALLBACK_VAR, callbackVarBase64); // Atur periode validitas menjadi 3600 detik. Date expiration = new Date(new Date().getTime() + 3600 * 1000); // Format waktu kedaluwarsa. SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); String expirationStr = dateFormat.format(expiration); // Bangun permintaan. GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, objectName); request.setMethod(HttpMethod.PUT); request.setExpiration(expiration); // Tambahkan header ke permintaan. request.setHeaders(headers); // Keluarkan nilai parameter callback dan callback-var. System.out.println("callback:"+callbackBase64); System.out.println("callback-var:"+callbackVarBase64); // Hasilkan URL yang ditandatangani. URL url = ossClient.generatePresignedUrl(request); // Keluarkan hasil. System.out.println("method: PUT,"); System.out.println(" expiration: " + expirationStr + ","); System.out.println(" url: " + url); } catch (OSSException oe) { System.out.println("Caught an OSSException, which means your request made it to OSS, " + "but was rejected with an error response for some reason."); System.out.println("Error Message:" + oe.getErrorMessage()); System.out.println("Error Code:" + oe.getErrorCode()); System.out.println("Request ID:" + oe.getRequestId()); System.out.println("Host ID:" + oe.getHostId()); } catch (ClientException ce) { System.out.println("Caught an ClientException, which means the client encountered " + "a serious internal problem while trying to communicate with OSS, " + "such as not being able to access the network."); System.out.println("Error Message:" + ce.getMessage()); } } }Gunakan URL yang ditandatangani tersebut untuk mengunggah objek.
curl
curl -X PUT \ -H "x-oss-callback: eyJjYWxsYmFja1VybCI6Imh0dHA6Ly93d3cuZXhhbXBsZS5jb20vY2FsbGJhY2siLCJjYWxsYmFja0JvZHkiOiJidWNrZXQ9JHtidWNrZXR9Jm9iamVjdD0ke29iamVjdH0mbXlfdmFyXzE9JHt4OnZhcjF9Jm15X3Zhcl8yPSR7eDp2YXIyfSJ9" \ -H "x-oss-callback-var: eyJ4OnZhcjEiOiJ2YWx1ZTEiLCJ4OnZhcjIiOiJ2YWx1ZTIifQ==" \ -T "C:\\Users\\demo.txt" \ "https://exampleobject.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T083238Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************%2F20241112%2Fcn-hangzhou%2Foss%2Faliyun_v4_request&x-oss-signature=ed5a******************************************************"Python
import requests def upload_file(signed_url, file_path, headers=None): """ Gunakan URL yang ditandatangani untuk mengunggah objek ke OSS. :param signed_url: URL yang ditandatangani. :param file_path: Path lengkap file lokal yang akan diunggah. :param headers: Header permintaan. Parameter ini opsional. :return: None """ if not headers: headers = {} try: with open(file_path, 'rb') as file: response = requests.put(signed_url, data=file, headers=headers) print(f"Status code: {response.status_code}") if response.status_code == 200: print("Objek diunggah menggunakan library.") else: print("Unggah gagal.") print(response.text) except Exception as e: print(f"Terjadi kesalahan: {e}") if __name__ == "__main__": # Ganti <signedUrl> dengan URL yang ditandatangani. signed_url = "<signedUrl>" # Tentukan path lengkap file lokal. Secara default, jika Anda tidak menentukan path lengkap file lokal, file lokal diunggah dari direktori tempat skrip disimpan. file_path = "C:\\Users\\demo.txt" headers = { "x-oss-callback": "eyJjYWxsYmFja1VybCI6Imh0dHA6Ly93d3cuZXhhbXBsZS5jb20vY2FsbGJhY2siLCJjYWxsYmFja0JvZHkiOiJidWNrZXQ9JHtidWNrZXR9Jm9iamVjdD0ke29iamVjdH0mbXlfdmFyXzE9JHt4OnZhcjF9Jm15X3Zhcl8yPSR7eDp2YXIyfSJ9", "x-oss-callback-var": "eyJ4OnZhcjEiOiJ2YWx1ZTEiLCJ4OnZhcjIiOiJ2YWx1ZTIifQ==", } upload_file(signed_url, file_path, headers)Go
package main import ( "bytes" "fmt" "io" "net/http" "os" ) func uploadFile(signedUrl string, filePath string, headers map[string]string) error { // Buka file. file, err := os.Open(filePath) if err != nil { return err } defer file.Close() // Baca konten. fileBytes, err := io.ReadAll(file) if err != nil { return err } // Buat permintaan. req, err := http.NewRequest("PUT", signedUrl, bytes.NewBuffer(fileBytes)) if err != nil { return err } // Tentukan header permintaan. for key, value := range headers { req.Header.Add(key, value) } // Kirim permintaan. client := &http.Client{} resp, err := client.Do(req) if err != nil { return err } defer resp.Body.Close() // Proses respons. fmt.Printf("Status code: %d\n", resp.StatusCode) if resp.StatusCode == 200 { fmt.Println("Objek diunggah menggunakan library.") } else { fmt.Println("Unggah gagal.") } body, _ := io.ReadAll(resp.Body) fmt.Println(string(body)) return nil } func main() { // Ganti <signedUrl> dengan URL yang ditandatangani. signedUrl := "<signedUrl>" // Tentukan path lengkap file lokal. Jika path file lokal tidak ditentukan, file lokal diunggah dari path proyek tempat program contoh berada. filePath := "C:\\Users\\demo.txt" // Tentukan header permintaan. Pastikan nilai header permintaan sama dengan yang ditentukan saat URL yang ditandatangani dihasilkan. headers := map[string]string{ "x-oss-callback": "eyJjYWxsYmFja1VybCI6Imh0dHA6Ly93d3cuZXhhbXBsZS5jb20vY2FsbGJhY2siLCJjYWxsYmFja0JvZHkiOiJidWNrZXQ9JHtidWNrZXR9Jm9iamVjdD0ke29iamVjdH0mbXlfdmFyXzE9JHt4OnZhcjF9Jm15X3Zhcl8yPSR7eDp2YXIyfSJ9", "x-oss-callback-var": "eyJ4OnZhcjEiOiJ2YWx1ZTEiLCJ4OnZhcjIiOiJ2YWx1ZTIifQ==", } err := uploadFile(signedUrl, filePath, headers) if err != nil { fmt.Printf("Terjadi kesalahan: %v\n", err) } }Java
import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPut; import org.apache.http.entity.FileEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import java.io.*; import java.net.URL; import java.util.*; public class SignUrlUpload { public static void main(String[] args) throws Throwable { CloseableHttpClient httpClient = null; CloseableHttpResponse response = null; // Ganti <signedUrl> dengan URL yang ditandatangani. URL signedUrl = new URL("<signedUrl>"); // Tentukan path lengkap file lokal. Jika path file lokal tidak ditentukan, file lokal diunggah dari path proyek tempat program contoh berada. String pathName = "C:\\Users\\demo.txt"; // Tentukan header permintaan, termasuk x-oss-callback dan x-oss-callback-var. Map<String, String> headers = new HashMap<String, String>(); headers.put("x-oss-callback", "eyJjYWxsYmFja1VybCI6Imh0dHA6Ly93d3cuZXhhbXBsZS5jb20vY2FsbGJhY2siLCJjYWxsYmFja0JvZHkiOiJidWNrZXQ9JHtidWNrZXR9Jm9iamVjdD0ke29iamVjdH0mbXlfdmFyXzE9JHt4OnZhcjF9Jm15X3Zhcl8yPSR7eDp2YXIyfSJ9"); headers.put("x-oss-callback-var", "eyJ4OnZhcjEiOiJ2YWx1ZTEiLCJ4OnZhcjIiOiJ2YWx1ZTIifQ=="); try { HttpPut put = new HttpPut(signedUrl.toString()); System.out.println(put); HttpEntity entity = new FileEntity(new File(pathName)); put.setEntity(entity); // Jika Anda mengonfigurasi header saat URL yang ditandatangani dihasilkan, header ini harus dikirim ke server saat URL yang ditandatangani digunakan untuk mengunggah file. Jika header yang dikirim ke server untuk perhitungan tanda tangan berbeda dengan header yang ditentukan saat URL yang ditandatangani dihasilkan, kesalahan tanda tangan akan dilaporkan. for(Map.Entry header: headers.entrySet()){ put.addHeader(header.getKey().toString(),header.getValue().toString()); } httpClient = HttpClients.createDefault(); response = httpClient.execute(put); System.out.println("Status code: "+response.getStatusLine().getStatusCode()); if(response.getStatusLine().getStatusCode() == 200){ System.out.println("Objek diunggah menggunakan library."); } System.out.println(response.toString()); } catch (Exception e){ e.printStackTrace(); } finally { response.close(); httpClient.close(); } } }PHP
<?php function uploadFile($signedUrl, $filePath, $headers = []) { // Periksa apakah file ada. if (!file_exists($filePath)) { echo "File tidak ada: $filePath\n"; return; } // Inisialisasi sesi cURL. $ch = curl_init(); // Atur opsi cURL. curl_setopt($ch, CURLOPT_URL, $signedUrl); curl_setopt($ch, CURLOPT_PUT, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_INFILE, fopen($filePath, 'rb')); curl_setopt($ch, CURLOPT_INFILESIZE, filesize($filePath)); curl_setopt($ch, CURLOPT_HTTPHEADER, array_map(function($key, $value) { return "$key: $value"; }, array_keys($headers), $headers)); // Jalankan permintaan cURL. $response = curl_exec($ch); // Periksa kode status HTTP. $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); // Tutup sesi cURL. curl_close($ch); // Keluarkan hasil echo "Status code: $httpCode\n"; if ($httpCode == 200) { echo "Objek diunggah menggunakan library.\n"; } else { echo "Unggah gagal.\n"; } echo $response . "\n"; } // Ganti <signedUrl> dengan URL yang ditandatangani. $signedUrl = "<signedUrl>"; // Tentukan path lengkap file lokal. Secara default, jika Anda tidak menentukan path lengkap file lokal, file lokal diunggah dari direktori tempat skrip disimpan. $filePath = "C:\\Users\\demo.txt"; $headers = [ "x-oss-callback" => "eyJjYWxsYmFja1VybCI6Imh0dHA6Ly93d3cuZXhhbXBsZS5jb20vY2FsbGJhY2siLCJjYWxsYmFja0JvZHkiOiJidWNrZXQ9JHtidWNrZXR9Jm9iamVjdD0ke29iamVjdH0mbXlfdmFyXzE9JHt4OnZhcjF9Jm15X3Zhcl8yPSR7eDp2YXIyfSJ9", "x-oss-callback-var" => "eyJ4OnZhcjEiOiJ2YWx1ZTEiLCJ4OnZhcjIiOiJ2YWx1ZTIifQ==", ]; uploadFile($signedUrl, $filePath, $headers); ?>