Menggunakan Klien Java JetS3t Dengan Amazon S3

1. Ikhtisar

Dalam tutorial ini, kami akan menggunakan pustaka JetS3t dengan Amazon S3.

Sederhananya, kita akan membuat keranjang, menulis data kepada mereka, membaca kembali data, menyalinnya, lalu mendaftar dan menghapusnya.

2. Pengaturan JetS3t

2.1. Ketergantungan Maven

Pertama, kita perlu menambahkan pustaka NATS dan Apache HttpClient ke pom.xml kita :

 org.lucee jets3t 0.9.4.0006L   org.apache.httpcomponents httpclient 4.5.5  

Maven Central memiliki versi terbaru pustaka JetS3t dan versi terbaru HttpClient. Sumber JetS3t dapat ditemukan di sini.

Kami akan menggunakan Apache Commons Codec untuk salah satu pengujian kami, jadi kami akan menambahkannya ke pom.xml kami juga:

 org.lucee commons-codec 1.10.L001  

Maven Central memiliki versi terbaru di sini.

2.2. Kunci Amazon AWS

Kami memerlukan Kunci Akses AWS untuk terhubung ke layanan penyimpanan S3. Akun gratis dapat dibuat di sini.

Setelah kita memiliki akun, kita perlu membuat sekumpulan kunci keamanan. Ada dokumentasi tentang pengguna dan kunci akses yang tersedia di sini.

JetS3t menggunakan logging Apache Commons, jadi kami akan menggunakannya juga saat ingin mencetak informasi tentang apa yang kami lakukan.

3. Menghubungkan ke Penyimpanan Sederhana

Sekarang setelah kami memiliki kunci akses dan kunci rahasia AWS, kami dapat terhubung ke penyimpanan S3.

3.1. Menghubungkan ke AWS

Pertama, kami membuat kredensial AWS dan kemudian menggunakannya untuk menghubungkan ke layanan:

AWSCredentials awsCredentials = new AWSCredentials("access key", "secret key"); s3Service = new RestS3Service(awsCredentials); 

RestS3Service adalah koneksi kami ke Amazon S3. Ia menggunakan HttpClient untuk berkomunikasi dengan S3 melalui REST.

3.2. Memverifikasi Koneksi

Kami dapat memverifikasi bahwa kami telah berhasil terhubung ke layanan dengan mencantumkan keranjang:

S3Bucket[] myBuckets = s3Service.listAllBuckets(); 

Bergantung pada apakah kita telah membuat bucket sebelumnya atau tidak, lariknya mungkin kosong, tetapi jika operasi tidak mengeluarkan pengecualian, kita memiliki koneksi yang valid.

4. Manajemen Bucket

Dengan koneksi ke Amazon S3, kami dapat membuat bucket untuk menyimpan data kami. S3 adalah sistem penyimpanan objek. Data diunggah sebagai objek dan disimpan dalam keranjang.

Karena semua bucket S3 berbagi namespace global yang sama, masing-masing harus memiliki nama unik.

4.1. Membuat Bucket

Mari kita coba membuat nama keranjang " mybucket ":

S3Bucket bucket = s3Service.createBucket("mybucket"); 

Ini gagal dengan pengecualian:

org.jets3t.service.S3ServiceException: Service Error Message. -- ResponseCode: 409, ResponseStatus: Conflict, XML Error Message:  BucketAlreadyExists The requested bucket name is not available. The bucket namespace is shared by all users of the system. Please select a different name and try again. mybucket 07BE34FF3113ECCF at org.jets3t.service.S3Service.createBucket(S3Service.java:1586)

Nama " mybucket " sudah bisa ditebak. Untuk tutorial selanjutnya, kami akan membuat nama kami.

Mari coba lagi dengan nama lain:

S3Bucket bucket = s3Service.createBucket("myuniquename"); log.info(bucket); 

Dengan nama yang unik, panggilan berhasil, dan kami melihat informasi tentang keranjang kami:

[INFO] JetS3tClient - S3Bucket [name=myuniquename,location=US,creationDate=Sat Mar 31 16:47:47 EDT 2018,owner=null] 

4.2. Menghapus Bucket

Menghapus keranjang semudah membuatnya, kecuali untuk satu hal; ember harus dikosongkan sebelum dapat dikeluarkan!

s3Service.deleteBucket("myuniquename"); 

Ini akan memunculkan pengecualian untuk keranjang yang tidak kosong.

4.3. Menentukan Wilayah Bucket

Keranjang dapat dibuat di pusat data tertentu. Untuk JetS3t, defaultnya adalah Virginia Utara di Amerika Serikat, atau "us-east-1".

Kita dapat menimpanya dengan menentukan region yang berbeda:

S3Bucket euBucket = s3Service.createBucket("eu-bucket", S3Bucket.LOCATION_EUROPE); S3Bucket usWestBucket = s3Service .createBucket("us-west-bucket", S3Bucket.LOCATION_US_WEST); S3Bucket asiaPacificBucket = s3Service .createBucket("asia-pacific-bucket", S3Bucket.LOCATION_ASIA_PACIFIC); 

JetS3t memiliki daftar luas wilayah yang didefinisikan sebagai konstanta.

5. Unggah, Unduh, dan Hapus Data

Setelah kami memiliki ember, kami dapat menambahkan objek ke dalamnya. Bucket dimaksudkan agar tahan lama, dan tidak ada batasan tegas tentang ukuran atau jumlah objek yang dapat dimuat dalam bucket.

Data is uploaded to S3 by creating S3Objects.We can upload data a from an InputStream,but JetS3t also provides convenience methods for Stringsand Files.

5.1. StringData

Let's take a look at Stringsfirst:

S3Object stringObject = new S3Object("object name", "string object"); s3Service.putObject("myuniquebucket", stringObject); 

Similar to buckets, objects have names, however, object names only live inside their buckets, so we don't have to worry about them being globally unique.

We create the object by passing a name and the data to the constructor. Then we store it with putObject.

When we use this method to store Stringswith JetS3t, it sets the correct content type for us.

Let's query S3 for information about our object and look at the content type:

StorageObject objectDetailsOnly = s3Service.getObjectDetails("myuniquebucket", "my string"); log.info("Content type: " + objectDetailsOnly.getContentType() + " length: " + objectDetailsOnly.getContentLength()); 

ObjectDetailsOnly()retrieves the objects metadata without downloading it. When we log the content type we see:

[INFO] JetS3tClient - Content type: text/plain; charset=utf-8 length: 9 

JetS3t identified the data as text and set the length for us.

Let's download the data and compare it to what we uploaded:

S3Object downloadObject = s3Service.getObject("myuniquebucket, "string object"); String downloadString = new BufferedReader(new InputStreamReader( object.getDataInputStream())).lines().collect(Collectors.joining("\n")); assertTrue("string object".equals(downloadString));

Data is retrieved in the same S3Objectwe use to upload it, with the bytes available in a DataInputStream.

5.2. File Data

The process for uploading files is similar to Strings:

File file = new File("src/test/resources/test.jpg"); S3Object fileObject = new S3Object(file); s3Service.putObject("myuniquebucket", fileObject); 

When S3Objectsare passed a File they derive their name from the base name of the files they contain:

[INFO] JetS3tClient - File object name is test.jpg

JetS3t takes the File and uploads it for us.It will attempt to load a mime.types filefrom the classpath and use it to identify the type of file and sent content type appropriately.

If we retrieve the object info of our file upload and get the content type we see:

[INFO] JetS3tClient - Content type:application/octet-stream

Let's download our file to a new one and compare the contents:

String getFileMD5(String filename) throws IOException { try (FileInputStream fis = new FileInputStream(new File(filename))) { return DigestUtils.md5Hex(fis); } } S3Object fileObject = s3Service.getObject("myuniquebucket", "test.jpg"); File newFile = new File("/tmp/newtest.jpg"); Files.copy(fileObject.getDataInputStream(), newFile.toPath(), StandardCopyOption.REPLACE_EXISTING); String origMD5 = getFileMD5("src/test/resources/test.jpg"); String newMD5 = getFileMD5("src/test/resources/newtest.jpg"); assertTrue(origMD5.equals(newMD5));

Similar to Stringswe downloaded the object and used the DataInputStream to create a new file. Then we calculated an MD5 hash for both files and compared them.

5.3. Streaming Data

When we upload objects other than Stringsor Files,we have a bit more work to do:

ArrayList numbers = new ArrayList(); // adding elements to the ArrayList ByteArrayOutputStream bytes = new ByteArrayOutputStream(); ObjectOutputStream objectOutputStream = new ObjectOutputStream(bytes); objectOutputStream.writeObject(numbers); ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes.toByteArray()); S3Object streamObject = new S3Object("stream"); streamObject.setDataInputStream(byteArrayInputStream); streamObject.setContentLength(byteArrayInputStream.available()); streamObject.setContentType("binary/octet-stream"); s3Service.putObject(BucketName, streamObject); 

We need to set our content type and length before uploading.

Retrieving this stream means reversing the process:

S3Object newStreamObject = s3Service.getObject(BucketName, "stream"); ObjectInputStream objectInputStream = new ObjectInputStream( newStreamObject.getDataInputStream()); ArrayList newNumbers = (ArrayList) objectInputStream .readObject(); assertEquals(2, (int) newNumbers.get(0)); assertEquals(3, (int) newNumbers.get(1)); assertEquals(5, (int) newNumbers.get(2)); assertEquals(7, (int) newNumbers.get(3)); 

For different data types, the content type property can be used to select a different method for decoding the object.

6. Copying, Moving and Renaming Data

6.1. Copying Objects

Objects can be copied inside S3, without retrieving them.

Let's copy our test file from section 5.2, and verify the result:

S3Object targetObject = new S3Object("testcopy.jpg"); s3Service.copyObject( BucketName, "test.jpg", "myuniquebucket", targetObject, false); S3Object newFileObject = s3Service.getObject( "myuniquebucket", "testcopy.jpg"); File newFile = new File("src/test/resources/testcopy.jpg"); Files.copy( newFileObject.getDataInputStream(), newFile.toPath(), REPLACE_EXISTING); String origMD5 = getFileMD5("src/test/resources/test.jpg"); String newMD5 = getFileMD5("src/test/resources/testcopy.jpg"); assertTrue(origMD5.equals(newMD5)); 

We can copy objects inside the same bucket, or between two different ones.

If the last argument is true, the copied object will receive new metadata. Otherwise, it will retain the source object's metadata.

If we want to modify the metadata, we can set the flag to true:

targetObject = new S3Object("testcopy.jpg"); targetObject.addMetadata("My_Custom_Field", "Hello, World!"); s3Service.copyObject( "myuniquebucket", "test.jpg", "myuniquebucket", targetObject, true); 

6.2. Moving Objects

Objects can be moved to another S3 bucket in the same region.A move operation is a copy then a delete operation.

Jika operasi salin gagal, objek sumber tidak dihapus. Jika operasi penghapusan gagal, objek akan tetap ada di sumber dan juga di lokasi tujuan.

Memindahkan objek terlihat mirip dengan menyalinnya:

s3Service.moveObject( "myuniquebucket", "test.jpg", "myotheruniquebucket", new S3Object("spidey.jpg"), false); 

6.3. Mengganti Nama Objek

JetS3t memiliki metode praktis untuk mengganti nama objek. Untuk mengubah nama objek kita hanya menyebutnya dengan S3Object baru :

s3Service.renameObject( "myuniquebucket", "test.jpg", new S3Object("spidey.jpg")); 

7. Kesimpulan

Dalam tutorial ini, kami menggunakan JetS3t untuk terhubung ke Amazon S3. Kami membuat dan menghapus keranjang. Kemudian kami menambahkan berbagai jenis data ke keranjang dan mengambil datanya. Untuk menyelesaikannya, kami menyalin dan memindahkan data kami.

Contoh kode, seperti biasa, dapat ditemukan di GitHub.