Amazon S3でJetS3t Javaクライアントを使用する

1概要

このチュートリアルでは、https://www.jets3t.org/[JetS3t]ライブラリとhttps://aws.amazon.com/s3/[Amazon S3]を使用します。]

簡単に言うと、バケツを作成し、データを書き込み、データを読み戻し、コピーしてから、一覧表示して削除します。

2 JetS3tセットアップ

2.1. Mavenの依存関係

まず、NATSライブラリとhttps://hc.apache.org/[Apache HttpClient]を pom.xml に追加する必要があります。

<dependency>
    <groupId>org.lucee</groupId>
    <artifactId>jets3t</artifactId>
    <version>0.9.4.0006L</version>
</dependency>
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.5</version>
</dependency>

Maven Centralにはhttps://search.maven.org/classic/#search%7Cga%7C1%7Cjets3t[最新バージョンのJetS3tライブラリ]とhttps://search.maven.org/classic/#artifactdetails%7Corgがあります。 .apache.httpcomponents%7Chttpclient%7C4.5.5%7Cjar[最新バージョンのHttpClient]。 JetS3tのソースはhttps://bitbucket.org/jmurty/jets3t/wiki/Home[ここ]にあります。

テストの1つにhttps://commons.apache.org/proper/commons-codec/[Apache Commons Codec]を使用するので、それを __pom.xml __tooに追加します。

<dependency>
    <groupId>org.lucee</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.10.L001</version>
</dependency>

Maven Centralの最新バージョンはhttps://search.maven.org/classic/#artifactdetails%7Corg.lucee%7Ccommons-codec%7C1.10.L001%7Cbundle[ここ]です。

2.2. Amazon AWSキー

  • S3ストレージサービスに接続するにはAWS Access Keysが必要です** 無料アカウントを作成することができますhttps://aws.amazon.com/free/?sc__ichannel=ha

アカウントを作成したら、https://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html[セキュリティキー]のセットを作成する必要があります。]ユーザーに関するドキュメントと利用可能なアクセスキーhttps://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html[ここ。]

JetS3tはApache Commonsのロギングを使っているので、私たちがしていることについての情報を印刷したいときにも使います。

3シンプルストレージへの接続

これでAWSのアクセスキーとシークレットキーを入手できたので、S3ストレージに接続できます。

3.1. AWSへの接続

まず、AWSの認証情報を作成し、それを使用してサービスに接続します。

AWSCredentials awsCredentials
  = new AWSCredentials("access key", "secret key");
s3Service = new RestS3Service(awsCredentials);
  • __ RestS3Service はAmazon S3への接続です。 ** HttpClient __を使用してRESTを介してS3と通信します。

3.2. 接続を確認する

バケットをリストすることで、サービスに正常に接続したことを確認できます。

S3Bucket[]myBuckets = s3Service.listAllBuckets();

以前にバケットを作成したかどうかによって、配列は空になることがありますが、操作で例外がスローされない場合は、有効な接続があります。

4バケツ管理

Amazon S3に接続すると、データを保持するためのバケットを作成できます。

S3はオブジェクトストレージシステムです。データはオブジェクトとしてアップロードされ、バケットに保存されます。

  • すべてのS3バケットは同じグローバル名前空間を共有しているので、それぞれに固有の名前が必要です。

4.1. バケットを作成する

mybucket 」というバケット名を作成してみましょう。

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

これは例外で失敗します。

org.jets3t.service.S3ServiceException: Service Error Message.
  -- ResponseCode: 409, ResponseStatus: Conflict, XML Error Message:
  <!--?xml version="1.0" encoding="UTF-8"?-->
  <code>BucketAlreadyExists</code> 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)

mybucket 」という名前は、予想通り、すでに使用されています。チュートリアルの残りの部分では、名前を付けます。

別の名前でもう一度試してみましょう。

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

ユニークな名前で、呼び出しは成功します、そして私達は私達のバケツについての情報を見ます:

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

4.2. バケットを削除する

バケツを削除することはそれを作成するのと同じくらい簡単ですが、1つだけ異なります。 ** バケットは削除する前に空にしてください。

s3Service.deleteBucket("myuniquename");

これは空ではないバケットに対して例外を投げます。

4.3. バケット領域の指定

  • バケットは特定のデータセンターに作成することができます。 ** JetS3tの場合、デフォルトはアメリカ合衆国のNorthern Virginia、または "us-east-1"です。

別のリージョンを指定することでこれをオーバーライドできます。

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には定数として定義された広範囲の領域のリストがあります。

5データのアップロード、ダウンロード、削除

バケットを作成したら、それにオブジェクトを追加できます。バケツは長持ちするように意図されており、バケツに入れることができるオブジェクトのサイズや数に厳しい制限はありません。

データは____S3Objectsを作成することによってS3にアップロードされます。

5.1. __String __Data

__Strings __firstを見てみましょう。

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

バケットと同様に、オブジェクトには名前がありますが、オブジェクト名はそのバケット内にのみ存在するため、それらがグローバルに一意であることを心配する必要はありません。

名前とデータをコンストラクタに渡すことでオブジェクトを作成します。

それからそれを putObject. で保存します。

このメソッドを使ってJetS3tに __Strings __を格納すると、正しいコンテンツタイプが設定されます。

オブジェクトに関する情報をS3に問い合わせてコンテンツタイプを見てみましょう。

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

__ObjectDetailsOnly() __は、ダウンロードせずにオブジェクトのメタデータを取得します。コンテンツタイプを記録すると、次のようになります。

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

JetS3tはデータをテキストとして識別し、長さを設定しました。

データをダウンロードして、アップロードしたものと比較しましょう。

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));

データは、アップロードに使用したのと同じ __S3Object で、 DataInputStream.__で使用可能なバイト数で取得されます。

5.2. ファイルデータ

ファイルをアップロードするプロセスは Strings に似ています。

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

__S3Objects file __を渡されるとき、それらはそれらが含むファイルのベース名からそれらの名前を得ます:

----[INFO]JetS3tClient - File object name is test.jpg
----
  • JetS3tは File を取得してアップロードします。 ** クラスパスからhttps://en.wikipedia.org/wiki/Media__type#mime.types[mime.typesファイル]をロードして、ファイルの種類と送信されたコンテンツの種類を適切に識別します。

ファイルアップロードのオブジェクト情報を取得してコンテンツタイプを取得すると、次のようになります。

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

ファイルを新しいファイルにダウンロードして内容を比較しましょう。

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));

__Strings weと同様にオブジェクトをダウンロードし、 DataInputStream__を使用して新しいファイルを作成しました。次に、両方のファイルについてMD5ハッシュを計算し、それらを比較しました。

5.3. ストリーミングデータ

  • __Strings または __Files以外のオブジェクトをアップロードするときは、もう少し作業が必要です。

ArrayList<Integer> 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);

アップロードする前にコンテンツタイプと長さを設定する必要があります。

このストリームを取得すると、プロセスが逆になります。

S3Object newStreamObject = s3Service.getObject(BucketName, "stream");

ObjectInputStream objectInputStream = new ObjectInputStream(
  newStreamObject.getDataInputStream());
ArrayList<Integer> newNumbers = (ArrayList<Integer>) 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));

データ型が異なると、content typeプロパティを使用して、オブジェクトをデコードするための異なる方法を選択できます。

6. データのコピー、移動、名前変更

6.1. オブジェクトのコピー

オブジェクトを取得せずに、S3内にコピーすることができます。

セクション5.2のテストファイルをコピーして、結果を確認しましょう。

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));

オブジェクトを同じバケット内、または2つの異なるバケット間でコピーできます。

最後の引数がtrueの場合、コピーされたオブジェクトは新しいメタデータを受け取ります。それ以外の場合は、ソースオブジェクトのメタデータが保持されます。

メタデータを変更したい場合は、フラグをtrueに設定できます。

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

6.2. 移動オブジェクト

  • オブジェクトは、同じリージョン内の別のS3バケットに移動できます。 ** 移動操作は、コピーしてから削除操作です。

コピー操作が失敗した場合、ソースオブジェクトは削除されません。削除操作が失敗した場合でも、オブジェクトはソース内にも宛先先にも存在します。

オブジェクトを移動することはそれをコピーすることに似ています:

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

6.3. オブジェクト名の変更

  • JetS3tはオブジェクトの名前を変更するための便利なメソッドを持っています。

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

7. 結論

このチュートリアルでは、JetS3tを使ってAmazon S3に接続しました。バケツを作成して削除しました。次に、さまざまな種類のデータをバケットに追加してデータを取得しました。まとめるために、データをコピーして移動しました。

コードサンプルは、いつものようにhttps://github.com/eugenp/tutorials/tree/master/aws[over GitHub]にあります。