Secara default, objek baru akan menimpa objek yang sudah ada dengan nama yang sama jika Anda memiliki izin akses yang diperlukan. Topik ini menjelaskan cara mencegah perilaku tersebut dengan mengatur header permintaan x-oss-forbid-overwrite untuk unggah simple, salin objek, dan unggah multi-bagian.
Catatan
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.
Unggah simple
Kode berikut menunjukkan cara mencegah penimpaan objek dengan nama yang sama selama unggah simple:
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.*;
import java.io.ByteArrayInputStream;
public class Demo {
public static void main(String[] args) throws Exception {
// Contoh ini menggunakan titik akhir wilayah China (Hangzhou). Gantilah dengan titik akhir aktual Anda.
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// Peroleh kredensial akses dari variabel lingkungan. Sebelum menjalankan kode ini, pastikan variabel lingkungan OSS_ACCESS_KEY_ID dan OSS_ACCESS_KEY_SECRET telah diatur.
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// Tentukan nama bucket. Misalnya, examplebucket.
String bucketName = "examplebucket";
// Tentukan path lengkap objek. Path lengkap tidak boleh mengandung nama bucket.
String objectName = "exampledir/object";
String content = "Hello OSS!";
// 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 sumber daya ketika instans OSSClient tidak lagi diperlukan.
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
OSS ossClient = OSSClientBuilder.create()
.endpoint(endpoint)
.credentialsProvider(credentialsProvider)
.clientConfiguration(clientBuilderConfiguration)
.region(region)
.build();
try {
// Buat objek PutObjectRequest.
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, new ByteArrayInputStream(content.getBytes()));
// Tentukan apakah objek dengan nama yang sama akan ditimpa selama unggah.
// Jika Anda tidak menentukan x-oss-forbid-overwrite, objek dengan nama yang sama akan ditimpa secara default.
// Jika Anda mengatur x-oss-forbid-overwrite ke false, objek dengan nama yang sama akan ditimpa.
// Jika Anda mengatur x-oss-forbid-overwrite ke true, objek dengan nama yang sama tidak akan ditimpa. Jika objek dengan nama yang sama sudah ada, program akan melaporkan kesalahan.
ObjectMetadata metadata = new ObjectMetadata();
metadata.setHeader("x-oss-forbid-overwrite", "true");
putObjectRequest.setMetadata(metadata);
// Unggah file.
ossClient.putObject(putObjectRequest);
} catch (OSSException oe) {
System.out.println("Terjadi OSSException, yang berarti permintaan Anda sampai ke OSS, "
+ "tetapi ditolak dengan tanggapan kesalahan karena suatu alasan.");
System.out.println("Pesan Kesalahan:" + oe.getErrorMessage());
System.out.println("Kode Kesalahan:" + oe.getErrorCode());
System.out.println("ID Permintaan:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("Terjadi ClientException, yang berarti klien mengalami "
+ "masalah internal serius saat mencoba berkomunikasi dengan OSS, "
+ "seperti tidak dapat mengakses jaringan.");
System.out.println("Pesan Kesalahan:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}Salin file
Salin objek kecil menggunakan CopyObjectRequest
Kode berikut menunjukkan cara mencegah penimpaan objek dengan nama yang sama saat menyalin objek kecil menggunakan CopyObjectRequest:
import com.aliyun.oss.*; import com.aliyun.oss.common.auth.*; import com.aliyun.oss.common.comm.SignVersion; import com.aliyun.oss.model.*; public class Demo { public static void main(String[] args) throws Exception { // Contoh ini menggunakan titik akhir wilayah China (Hangzhou). Gantilah dengan titik akhir aktual Anda. String endpoint = "https://oss-cn-hangzhou.aliyuncs.com"; // Peroleh kredensial akses dari variabel lingkungan. Sebelum menjalankan kode ini, pastikan variabel lingkungan OSS_ACCESS_KEY_ID dan OSS_ACCESS_KEY_SECRET telah diatur. EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // Tentukan nama bucket sumber. String sourceBucketName = "srcexamplebucket"; // Tentukan path lengkap objek sumber. Path lengkap tidak boleh mengandung nama bucket. String sourceObjectName = "srcexampleobject.txt"; // Tentukan nama bucket tujuan. Bucket tujuan harus berada di wilayah yang sama dengan bucket sumber. String destinationBucketName = "desexamplebucket"; // Tentukan path lengkap objek tujuan. Path lengkap tidak boleh mengandung nama bucket. String destinationObjectName = "desexampleobject.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 sumber daya ketika instans OSSClient tidak lagi diperlukan. ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration(); clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); OSS ossClient = OSSClientBuilder.create() .endpoint(endpoint) .credentialsProvider(credentialsProvider) .clientConfiguration(clientBuilderConfiguration) .region(region) .build(); try { // Buat objek CopyObjectRequest. CopyObjectRequest copyObjectRequest = new CopyObjectRequest(sourceBucketName, sourceObjectName, destinationBucketName, destinationObjectName); // Atur metadata objek baru. ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentType("text/html"); // Tentukan apakah objek dengan nama yang sama akan ditimpa selama operasi salin. // Jika Anda tidak menentukan x-oss-forbid-overwrite, objek dengan nama yang sama akan ditimpa secara default. // Jika Anda mengatur x-oss-forbid-overwrite ke false, objek dengan nama yang sama akan ditimpa. // Jika Anda mengatur x-oss-forbid-overwrite ke true, objek dengan nama yang sama tidak akan ditimpa. Jika objek dengan nama yang sama sudah ada, program akan melaporkan kesalahan. metadata.setHeader("x-oss-forbid-overwrite", "true"); copyObjectRequest.setNewObjectMetadata(metadata); // Salin objek. CopyObjectResult result = ossClient.copyObject(copyObjectRequest); System.out.println("ETag: " + result.getETag() + " LastModified: " + result.getLastModified()); } catch (OSSException oe) { System.out.println("Terjadi OSSException, yang berarti permintaan Anda sampai ke OSS, " + "tetapi ditolak dengan tanggapan kesalahan karena suatu alasan."); System.out.println("Pesan Kesalahan:" + oe.getErrorMessage()); System.out.println("Kode Kesalahan:" + oe.getErrorCode()); System.out.println("ID Permintaan:" + oe.getRequestId()); System.out.println("Host ID:" + oe.getHostId()); } catch (ClientException ce) { System.out.println("Terjadi ClientException, yang berarti klien mengalami " + "masalah internal serius saat mencoba berkomunikasi dengan OSS, " + "seperti tidak dapat mengakses jaringan."); System.out.println("Pesan Kesalahan:" + ce.getMessage()); } finally { if (ossClient != null) { ossClient.shutdown(); } } } }Salin objek besar
Kode berikut menunjukkan cara mencegah penimpaan objek dengan nama yang sama saat menyalin objek besar menggunakan salin multi-bagian:
import com.aliyun.oss.*; import com.aliyun.oss.common.auth.*; import com.aliyun.oss.common.comm.SignVersion; import com.aliyun.oss.model.*; import java.util.ArrayList; import java.util.List; public class Demo { public static void main(String[] args) throws Exception { // Contoh ini menggunakan titik akhir wilayah China (Hangzhou). Gantilah dengan titik akhir aktual Anda. String endpoint = "https://oss-cn-hangzhou.aliyuncs.com"; // Peroleh kredensial akses dari variabel lingkungan. Sebelum menjalankan kode ini, pastikan variabel lingkungan OSS_ACCESS_KEY_ID dan OSS_ACCESS_KEY_SECRET telah diatur. EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // Tentukan nama bucket sumber. String sourceBucketName = "srcexamplebucket"; // Tentukan path lengkap objek sumber. Path lengkap tidak boleh mengandung nama bucket. String sourceObjectName = "srcexampleobject.txt"; // Tentukan nama bucket tujuan. Bucket tujuan harus berada di wilayah yang sama dengan bucket sumber. String destinationBucketName = "desexamplebucket"; // Tentukan path lengkap objek tujuan. Path lengkap tidak boleh mengandung nama bucket. String destinationObjectName = "desexampleobject.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 sumber daya ketika instans OSSClient tidak lagi diperlukan. ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration(); clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); OSS ossClient = OSSClientBuilder.create() .endpoint(endpoint) .credentialsProvider(credentialsProvider) .clientConfiguration(clientBuilderConfiguration) .region(region) .build(); try { ObjectMetadata objectMetadata = ossClient.getObjectMetadata(sourceBucketName, sourceObjectName); // Dapatkan ukuran objek yang akan disalin. long contentLength = objectMetadata.getContentLength(); // Atur ukuran bagian menjadi 10 MB. long partSize = 1024 * 1024 * 10; // Hitung jumlah total bagian. int partCount = (int) (contentLength / partSize); if (contentLength % partSize != 0) { partCount++; } System.out.println("total part count:" + partCount); // Inisialisasi tugas salin. Anda dapat menentukan metadata objek tujuan dalam InitiateMultipartUploadRequest. InitiateMultipartUploadRequest initiateMultipartUploadRequest = new InitiateMultipartUploadRequest(destinationBucketName, destinationObjectName); // Tentukan apakah objek dengan nama yang sama akan ditimpa selama operasi salin. // Jika Anda tidak menentukan x-oss-forbid-overwrite, objek dengan nama yang sama akan ditimpa secara default. // Jika Anda mengatur x-oss-forbid-overwrite ke false, objek dengan nama yang sama akan ditimpa. // Jika Anda mengatur x-oss-forbid-overwrite ke true, objek dengan nama yang sama tidak akan ditimpa. Jika objek dengan nama yang sama sudah ada, program akan melaporkan kesalahan. ObjectMetadata metadata = new ObjectMetadata(); metadata.setHeader("x-oss-forbid-overwrite", "true"); initiateMultipartUploadRequest.setObjectMetadata(metadata); InitiateMultipartUploadResult initiateMultipartUploadResult = ossClient.initiateMultipartUpload(initiateMultipartUploadRequest); String uploadId = initiateMultipartUploadResult.getUploadId(); // Salin bagian-bagian. List<PartETag> partETags = new ArrayList<PartETag>(); for (int i = 0; i < partCount; i++) { // Hitung ukuran setiap bagian. long skipBytes = partSize * i; long size = partSize < contentLength - skipBytes ? partSize : contentLength - skipBytes; // Buat UploadPartCopyRequest. Anda dapat menentukan kondisi dalam UploadPartCopyRequest. UploadPartCopyRequest uploadPartCopyRequest = new UploadPartCopyRequest(sourceBucketName, sourceObjectName, destinationBucketName, destinationObjectName); uploadPartCopyRequest.setUploadId(uploadId); uploadPartCopyRequest.setPartSize(size); uploadPartCopyRequest.setBeginIndex(skipBytes); uploadPartCopyRequest.setPartNumber(i + 1); UploadPartCopyResult uploadPartCopyResult = ossClient.uploadPartCopy(uploadPartCopyRequest); // Simpan ETag bagian yang dikembalikan ke partETags. partETags.add(uploadPartCopyResult.getPartETag()); } // Selesaikan tugas salin multi-bagian. CompleteMultipartUploadRequest completeMultipartUploadRequest = new CompleteMultipartUploadRequest( destinationBucketName, destinationObjectName, uploadId, partETags); // Tentukan apakah objek dengan nama yang sama akan ditimpa selama operasi salin. // Jika Anda tidak menentukan x-oss-forbid-overwrite, objek dengan nama yang sama akan ditimpa secara default. // Jika Anda mengatur x-oss-forbid-overwrite ke false, objek dengan nama yang sama akan ditimpa. // Jika Anda mengatur x-oss-forbid-overwrite ke true, objek dengan nama yang sama tidak akan ditimpa. Jika objek dengan nama yang sama sudah ada, program akan melaporkan kesalahan. completeMultipartUploadRequest.addHeader("x-oss-forbid-overwrite", "true"); ossClient.completeMultipartUpload(completeMultipartUploadRequest); } catch (OSSException oe) { System.out.println("Terjadi OSSException, yang berarti permintaan Anda sampai ke OSS, " + "tetapi ditolak dengan tanggapan kesalahan karena suatu alasan."); System.out.println("Pesan Kesalahan:" + oe.getErrorMessage()); System.out.println("Kode Kesalahan:" + oe.getErrorCode()); System.out.println("ID Permintaan:" + oe.getRequestId()); System.out.println("Host ID:" + oe.getHostId()); } catch (ClientException ce) { System.out.println("Terjadi ClientException, yang berarti klien mengalami " + "masalah internal serius saat mencoba berkomunikasi dengan OSS, " + "seperti tidak dapat mengakses jaringan."); System.out.println("Pesan Kesalahan:" + ce.getMessage()); } finally { if (ossClient != null) { ossClient.shutdown(); } } } }
Unggah multi-bagian
Kode berikut menunjukkan cara mencegah penimpaan objek dengan nama yang sama selama unggah multi-bagian:
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
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 {
// Contoh ini menggunakan titik akhir wilayah China (Hangzhou). Gantilah dengan titik akhir aktual Anda.
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// Peroleh kredensial akses dari variabel lingkungan. Sebelum menjalankan kode ini, pastikan variabel lingkungan OSS_ACCESS_KEY_ID dan OSS_ACCESS_KEY_SECRET telah diatur.
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// Tentukan nama bucket. Misalnya, examplebucket.
String bucketName = "examplebucket";
// Tentukan path lengkap objek. Path lengkap tidak boleh mengandung nama bucket.
String objectName = "exampledir/object";
// 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 sumber daya ketika instans OSSClient tidak lagi diperlukan.
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);
// Tentukan apakah objek dengan nama yang sama akan ditimpa selama unggah multi-bagian.
// Jika Anda tidak menentukan x-oss-forbid-overwrite, objek dengan nama yang sama akan ditimpa secara default.
// Jika Anda mengatur x-oss-forbid-overwrite ke false, objek dengan nama yang sama akan ditimpa.
// Jika Anda mengatur x-oss-forbid-overwrite ke true, objek dengan nama yang sama tidak akan ditimpa. Jika objek dengan nama yang sama sudah ada, program akan melaporkan kesalahan.
ObjectMetadata metadata = new ObjectMetadata();
metadata.setHeader("x-oss-forbid-overwrite", "true");
request.setObjectMetadata(metadata);
// Inisialisasi unggah multi-bagian.
InitiateMultipartUploadResult upresult = ossClient.initiateMultipartUpload(request);
// ID unggah dikembalikan. Ini adalah pengenal unik untuk event unggah multi-bagian. Anda dapat menggunakan ID ini untuk melakukan operasi terkait, seperti membatalkan atau menanyakan status unggah multi-bagian.
String uploadId = upresult.getUploadId();
// partETags adalah kumpulan objek PartETag. PartETag terdiri dari ETag dan nomor bagian suatu bagian.
List<PartETag> partETags = new ArrayList<PartETag>();
// Hitung jumlah bagian.
final long partSize = 1 * 1024 * 1024L; // 1 MB
final File sampleFile = new File("<localFile>");
long fileLength = sampleFile.length();
int partCount = (int) (fileLength / partSize);
if (fileLength % partSize != 0) {
partCount++;
}
// Unggah bagian-bagian dalam perulangan.
for (int i = 0; i < partCount; i++) {
long startPos = i * partSize;
long curPartSize = (i + 1 == partCount) ? (fileLength - startPos) : partSize;
InputStream instream = new FileInputStream(sampleFile);
// Lewati bagian-bagian yang telah diunggah.
instream.skip(startPos);
UploadPartRequest uploadPartRequest = new UploadPartRequest();
uploadPartRequest.setBucketName(bucketName);
uploadPartRequest.setKey(objectName);
uploadPartRequest.setUploadId(uploadId);
uploadPartRequest.setInputStream(instream);
// Atur ukuran bagian. Ukuran minimum setiap bagian adalah 100 KB, kecuali bagian terakhir.
uploadPartRequest.setPartSize(curPartSize);
// Atur nomor bagian. Setiap bagian yang diunggah memiliki nomor bagian yang berkisar antara 1 hingga 10.000. Jika nomor bagian berada di luar rentang ini, OSS akan mengembalikan kode kesalahan InvalidArgument.
uploadPartRequest.setPartNumber( i + 1);
// Bagian tidak perlu diunggah secara berurutan dan dapat diunggah dari klien yang berbeda. OSS menggabungkan bagian-bagian tersebut menjadi satu objek lengkap berdasarkan nomor bagiannya.
UploadPartResult uploadPartResult = ossClient.uploadPart(uploadPartRequest);
// Setelah setiap bagian diunggah, respons OSS berisi PartETag. PartETag ini disimpan ke partETags.
partETags.add(uploadPartResult.getPartETag());
}
// Buat objek CompleteMultipartUploadRequest.
// Untuk menyelesaikan unggah multi-bagian, Anda harus menyediakan semua partETags yang valid. Setelah OSS menerima partETags yang dikirimkan, OSS akan memverifikasi setiap bagian. Ketika semua bagian telah diverifikasi, OSS akan menggabungkannya menjadi satu objek lengkap.
CompleteMultipartUploadRequest completeMultipartUploadRequest =
new CompleteMultipartUploadRequest(bucketName, objectName, uploadId, partETags);
// Tentukan apakah objek dengan nama yang sama akan ditimpa selama unggah multi-bagian.
// Jika Anda tidak menentukan x-oss-forbid-overwrite, objek dengan nama yang sama akan ditimpa secara default.
// Jika Anda mengatur x-oss-forbid-overwrite ke false, objek dengan nama yang sama akan ditimpa.
// Jika Anda mengatur x-oss-forbid-overwrite ke true, objek dengan nama yang sama tidak akan ditimpa. Jika objek dengan nama yang sama sudah ada, program akan melaporkan kesalahan.
completeMultipartUploadRequest.addHeader("x-oss-forbid-overwrite", "true");
// Selesaikan unggah.
CompleteMultipartUploadResult completeMultipartUploadResult = ossClient.completeMultipartUpload(completeMultipartUploadRequest);
} catch (OSSException oe) {
System.out.println("Terjadi OSSException, yang berarti permintaan Anda sampai ke OSS, "
+ "tetapi ditolak dengan tanggapan kesalahan karena suatu alasan.");
System.out.println("Pesan Kesalahan:" + oe.getErrorMessage());
System.out.println("Kode Kesalahan:" + oe.getErrorCode());
System.out.println("ID Permintaan:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("Terjadi ClientException, yang berarti klien mengalami "
+ "masalah internal serius saat mencoba berkomunikasi dengan OSS, "
+ "seperti tidak dapat mengakses jaringan.");
System.out.println("Pesan Kesalahan:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}Referensi
Untuk kode contoh lengkap yang menunjukkan cara mencegah penimpaan objek dengan nama yang sama dalam berbagai skenario unggah, lihat contoh GitHub.
Untuk informasi lebih lanjut tentang operasi API untuk unggah simple, lihat PutObject.
Untuk informasi lebih lanjut tentang operasi API untuk menyalin objek, lihat CopyObject.
Untuk informasi lebih lanjut tentang operasi API untuk unggah multi-bagian, lihat InitiateMultipartUpload dan CompleteMultipartUpload.