0
1

AWS SDK for JavaでS3オブジェクトの一覧を取得する2つの方法

Last updated at Posted at 2024-09-17

課題

AWS SDK for Javaで、S3オブジェクトの一覧を取得する機能を利用するとき、日本語でまとまった情報を入手するのに苦労しました。

解決方針

どのようにSDKを利用したか、この記事にまとめます。

方法

前提

  • Javaバージョン: 17
  • AWS SDKバージョン: v2

共通の注意点

  • 1回のリクエストで、すべてのオブジェクトが取得されるとは限りません。
    • 取得したオブジェクト一覧を格納したクラスには、以下の情報が含まれます。
      • a. 取得しきれなかったオブジェクトがあるか否か
      • b. 取得したオブジェクト一覧末尾の、次のオブジェクトを示すトークン
        • 取得しきれなかったオブジェクトを取得する際に、このトークンが示す位置から取得を開始します。

バージョニングが無効のとき

software.amazon.awssdk.services.s3.model.ListObjectsV2Requestクラスを利用します。

一例として、以下のgetAllS3Contentsメソッドでは、バケット内にあるすべてのオブジェクトを、リストに格納して返却しています。

  // S3クライアントを用意
  private final S3Client s3Client;

  // 初回に呼び出すメソッド
  public List<S3Object> getAllS3Contents(String bucketName) {
    return getAllS3Contents(bucketName, new ArrayList<S3Object>(), null);
  }

  // 再帰的に呼び出すメソッド
  private List<S3Object> getAllS3Contents(String bucketName, List<S3Object> objects, String continuationToken) {
    // リクエスト作成
    var listReq = ListObjectsV2Request.builder()
                                      .bucket(bucketName)
                                      .continuationToken(continuationToken)
                                      .build();

    // レスポンス取得
    var res = s3Client.listObjectsV2(listReq);
    // S3オブジェクトリスト取得
    var currentObjects = res.contents();
    // 前のステップで取得したS3オブジェクトリストを連結
    objects.addAll(currentObjects);
    // 次のステップで取得を開始する位置
    var nextContinuationToken = res.nextContinuationToken(); // (b, aが`false`の場合は`null`)

    // 一度にすべてのS3オブジェクトを取得しきれなかった場合、S3オブジェクトリストと開始位置を更新して、このメソッドを再帰的に呼び出す
    if (res.isTruncated()) { // (a)
      return getAllS3Contents(bucketName, objects, nextContinuationToken);
    }

    return objects;
  }

バージョニングが有効のとき

software.amazon.awssdk.services.s3.model.ListObjectVersionsRequestクラスを利用します。

一例として、以下のgetAllS3Versionsメソッドでは、バケット内にあるすべてのオブジェクトバージョンを、リストに格納して返却しています。

以下の点以外は、バージョニングが無効のときと同じです。

  • 返り値の型をObjectVersionに変更。
  • 次のオブジェクトを示すトークン(b)に、バージョンを示す情報を追加。
  // S3クライアントを用意
  private final S3Client s3Client;

  // 初回に呼び出すメソッド
  public List<ObjectVersion> getAllS3Versions(String bucketName) {
    return getAllS3Versions(bucketName, new ArrayList<ObjectVersion>(), null, null);
  }

  // 再帰的に呼び出すメソッド
  private List<ObjectVersion> getAllS3Versions(String bucketName, List<ObjectVersion> objVerList, String keyMarker, String versionIdMarker) {
    // リクエスト作成
    var listReq = ListObjectVersionsRequest.builder()
                                      .bucket(bucketName)
                                      .keyMarker(keyMarker)
                                      .versionIdMarker(versionIdMarker)
                                      .build();

    // レスポンス取得
    var res = s3Client.listObjectVersions(listReq);
    // S3オブジェクトリスト取得
    var currentVersions = res.versions();
    // 前のステップで取得したS3オブジェクトリストを連結
    objVerList.addAll(currentVersions);
    // 次のステップで取得を開始する位置
    var nextKeyMarker = res.nextKeyMarker(); // (b, aが`false`の場合は`null`)
    var nextVersionIdMarker = res.nextVersionIdMarker(); // (b, aが`false`の場合は`null`)

    // 一度にすべてのS3オブジェクトを取得しきれなかった場合、S3オブジェクトリストと開始位置を更新して、このメソッドを再帰的に呼び出す
    if (res.isTruncated()) { // (a)
      return getAllS3Versions(bucketName, objVerList, nextKeyMarker, nextVersionIdMarker);
    }

    return objVerList;
  }

参考資料

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1