App Engine スタンダード環境で Java から Cloud Storage を使う

Java 用の Bookshelf のチュートリアルのこのパートでは、画像を Google Cloud Storage に格納する方法を説明します。

このページは複数ページからなるチュートリアルの一部です。説明の最初から設定手順を確認するには、Java Bookshelf アプリに移動してください。

Cloud Storage バケットの作成

Cloud Storage バケットを作成する手順は次のとおりです。バケットは、Cloud Storage でデータを格納する基本的なコンテナです。

バケットを作成するには:

  1. ターミナル ウィンドウで次のコマンドを実行します。

    gsutil mb gs://[YOUR-BUCKET-NAME]

  2. バケットのデフォルト ACL を public-read に設定します。これによりユーザーは、自身がアップロードした画像を見られるようになります。

    gsutil defacl set public-read gs://[YOUR-BUCKET-NAME]

ローカルマシンでのアプリの実行

アプリをローカルで実行するには:

  1. getting-started-java/bookshelf-standard/3-binary-data ディレクトリで次のコマンドを入力し、ローカル ウェブサーバーを起動します。

    mvn -Plocal clean appengine:devserver -Dbookshelf.bucket=[YOUR-BUCKET]
    [YOUR_BUCKET] は、使用するバケット名に置き換えてください。
  2. ウェブブラウザで http://localhost:8080 に移動します。

これで、アプリのウェブページを閲覧できます。また、表紙画像を付けて書籍を追加し、追加した書籍を編集、削除することもできます。

App Engine スタンダード環境へのアプリのデプロイ

アプリを App Engine スタンダード環境にデプロイするには:

  1. Bookshelf アプリケーションのローカルでの演習を完了します。特に、少なくとも 1 つの書籍を作成して [My Books] をクリックしておきます。これにより、Bookshelf とともにアップロードされる、必要な Cloud Datastore のインデックスが作成されます。clean を使用してアプリケーションをビルドすると、そのローカル インデックスが削除されます。したがって、デプロイするアプリケーションのビルドでは必ずこの作業を行ってください。
  2. getting-started-java/bookshelf-standard/3-binary-data ディレクトリで、次のコマンドを入力してアプリをデプロイします。
    mvn appengine:update -Dappengine.appId=[YOUR-PROJECT-ID] -Dappengine.version=[YOUR-VERSION] -Dbookshelf.bucket=[YOUR-BUCKET].appspot.com
    [YOUR-PROJECT-ID] を実際のプロジェクト ID に、[YOUR-VERSION] を実際のバージョン(12 などの文字列値)に置き換えます。
  3. ウェブブラウザに次のアドレスを入力します。
    https://[YOUR-PROJECT-ID].appspot.com
    [YOUR-PROJECT-ID] を実際のプロジェクト ID に置き換えます。

アプリを更新した場合は、最初にデプロイしたときと同じコマンドを使って更新バージョンを再デプロイできます。同じプロジェクト ID とバージョンを指定することにより、現在デプロイされているアプリが上書きされます。更新の際に別のバージョン文字列を指定すると、アプリの新しいバージョンが作成されて、それが現在の提供バージョンに昇格されます。

アプリの提供バージョン以外のバージョンを削除することで、コストを削減できます。

アプリのバージョンを削除する手順は次のとおりです。

  1. GCP Console の [App Engine のバージョン] ページに移動します。

    [バージョン] ページに移動

  2. 削除したい、デフォルト以外のアプリのバージョンの横にあるチェックボックスをクリックします。
  3. ページ上部にある [削除] ボタンをクリックし、アプリのバージョンを削除します。

課金対象のリソースをクリーンアップする方法の詳細については、このチュートリアルの最後のステップにあるクリーンアップ セクションを参照してください。

アプリケーションの構造

バイナリデータの構造の例

ここではバイナリデータ(この例では画像)の格納場所として Cloud Storage が使われます。さらに書籍情報の格納場所としても Cloud Datastore が使われます。

コードを理解する

このセクションでは、アプリケーションのコードとその動作を順を追って説明します。

ユーザーのアップロードに対応する

Google Cloud Storage API for Java の使い方は簡単です。ほとんどの場合、ローカルな認証は 1 行で記述できます。

static {
  storage = StorageOptions.getDefaultInstance().getService();
}

blob を Cloud Storage にアップロードする

アップロードする前に、そのファイルが要件を満たしていることを確認してください。

/**
 * Checks that the file extension is supported.
 */
private void checkFileExtension(String fileName) throws ServletException {
  if (fileName != null && !fileName.isEmpty() && fileName.contains(".")) {
    String[] allowedExt = { ".jpg", ".jpeg", ".png", ".gif" };
    for (String ext : allowedExt) {
      if (fileName.endsWith(ext)) {
        return;
      }
    }
    throw new ServletException("file must be an image");
  }
}

次に、タイムスタンプを付加してファイル名を一意にします。storage.create で、bucketName および fileName を指定して作成した BlobInfo を受け渡し、さらにアクセス制御リストを設定することで、全ユーザーが当該ファイルの InputStream を読み込んで受け渡すことができるようにします。これによりオブジェクトの公開 URL が得られます。

/**
 * Uploads a file to Google Cloud Storage to the bucket specified in the BUCKET_NAME
 * environment variable, appending a timestamp to end of the uploaded filename.
 */
@SuppressWarnings("deprecation")
public String uploadFile(FileItemStream fileStream, final String bucketName)
    throws IOException, ServletException {
  checkFileExtension(fileStream.getName());

  DateTimeFormatter dtf = DateTimeFormat.forPattern("-YYYY-MM-dd-HHmmssSSS");
  DateTime dt = DateTime.now(DateTimeZone.UTC);
  String dtString = dt.toString(dtf);
  final String fileName = fileStream.getName() + dtString;

  // the inputstream is closed by default, so we don't need to close it here
  BlobInfo blobInfo =
      storage.create(
          BlobInfo
              .newBuilder(bucketName, fileName)
              // Modify access list to allow all users with link to read file
              .setAcl(new ArrayList<>(Arrays.asList(Acl.of(User.ofAllUsers(), Role.READER))))
              .build(),
          fileStream.openStream());
  // return the public download link
  return blobInfo.getMediaLink();
}
このページは役立ちましたか?評価をお願いいたします。