| |

Spring Boot(Gradle)でAmazon S3を利用するにはS3ClientConfigの基本・カスタム設定とS3Presigner実装

Amazon S3はファイルシステムではなくオブジェクトストレージであり、各ファイル(オブジェクト)はバケットの中にキーとメタデータを持つ単位として保存されます。バケットはコンテナのような役割を果たし、世界中のリージョンに分散して配置されます。Spring BootからS3を扱う際は、AWS SDK v2とGradleを利用してアプリケーションにS3クライアントを注入し、設定を柔軟にカスタマイズできます。

この記事では、GradleによるS3の依存関係設定からS3ClientConfigの基本設定とカスタム設定、そしてプレサインドURLを生成するS3Presignerの使い方までを詳しく解説します。最後に概念図も掲載するので、全体の流れをイメージしやすくなるはずです。

GradleでAWS SDK v2を実装する

S3を利用するにはAWS SDK v2のS3モジュールを依存関係に追加します。Gradleの場合、build.gradleに次のような設定を追加します。

plugins {
    id 'org.springframework.boot' version '3.2.5'
    id 'io.spring.dependency-management' version '1.1.4'
    id 'java'
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter'
    implementation platform('software.amazon.awssdk:bom:2.25.9')
    implementation 'software.amazon.awssdk:s3'
    implementation 'software.amazon.awssdk:netty-nio-client'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

AWS SDK v2ではBOM【Bill of Materials】を使うことでSDK各モジュールのバージョン整合性を保てます。またS3はHTTP通信を行うため、netty-nio-clientなどのHTTPクライアントが必要です。

基本的な設定:application.yml

Spring Bootアプリケーションでは、S3クライアントのリージョンや認証情報をapplication.ymlapplication.propertiesで指定できます。例えば次のように定義します。

cloud:
  aws:
    region:
      static: ap-northeast-1
    credentials:
      access-key: YOUR_ACCESS_KEY
      secret-key: YOUR_SECRET_KEY
    s3:
      bucket: your-bucket-name
    stack:
      auto: false

この設定ではリージョンをap-northeast-1に固定し、AWSアクセスキーとシークレットキーを指定しています。実際の運用では環境変数やAWS CLIプロファイルを利用することが推奨されます。

Spring Cloud AWSを使用している場合は、スターターが自動的にS3Clientビーンを生成し、クロスリージョンアクセスもサポートします。ただし、カスタム設定を行いたい場合は自前でS3Clientビーンを定義します。

S3ClientConfigのカスタム設定

AWS SDK v2ではS3ConfigurationクラスでS3クライアントの動作を細かく制御できます。主なカスタム項目と役割を表にまとめます。

設定項目デフォルト説明
accelerateModeEnabledfalseAmazon S3 Transfer Accelerationを有効化。CloudFront経由で高速アップロードする場合に利用します。
pathStyleAccessEnabledfalseバケット名をURLパスとして指定するパススタイルアクセスを許可します。リージョンのDNS名解決制約やローカルスタック用に有効にすることがあります。
checksumValidationEnabledtrueサーバーから返されるEtagやチェックサムを検証し、データ破損を防ぎます。
chunkedEncodingEnabledtrueマルチパートアップロード時にチャンク転送署号を行います。
useArnRegionEnabledfalseバケットARNに含まれるリージョンを使用するかどうか。クロスリージョンS3にアクセスするときに設定します。
useExpectContinueEnabledtrueHTTP 1.1の Expect: 100-continue ヘッダーを送信してアップロード開始時の待ち時間を短縮します。

カスタムS3Clientの実装例

以下はSpring Bootアプリケーションでカスタム設定を施したS3Clientビーンを登録する例です。HTTPクライアント、リージョン、認証情報を指定した上で、S3Configurationによるカスタム設定を利用しています。

import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
import software.amazon.awssdk.http.HttpExecuteTimeout;
import software.amazon.awssdk.http.nio.netty.NettyNioAsyncHttpClient;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.S3Configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class S3ClientConfig {
    @Bean
    public S3Client s3Client() {
        // 認証情報【開発環境では環境変数やプロファイルを利用推奨】
        AwsBasicCredentials credentials = AwsBasicCredentials.create(
            "YOUR_ACCESS_KEY", "YOUR_SECRET_KEY");

        // HTTPクライアント
        var httpClient = NettyNioAsyncHttpClient.builder()
            .build();

        // S3Configurationのカスタマイズ
        S3Configuration s3Config = S3Configuration.builder()
            .checksumValidationEnabled(true)
            .chunkedEncodingEnabled(true)
            .pathStyleAccessEnabled(false)
            .accelerateModeEnabled(false)
            .useArnRegionEnabled(false)
            .useExpectContinueEnabled(true)
            .build();

        return S3Client.builder()
            .httpClient(httpClient)
            .region(Region.AP_NORTHEAST_1)
            .credentialsProvider(StaticCredentialsProvider.create(credentials))
            .serviceConfiguration(s3Config)
            .overrideConfiguration(ClientOverrideConfiguration.builder()
                .build())
            .build();
    }
}

S3操作サービスの例

登録したS3Clientビーンを使ってオブジェクトのアップロードや取得を行うサービスクラスを例示します。

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.*;

@Service
@RequiredArgsConstructor
public class S3Service {
    private final S3Client s3Client;
    private final String bucketName = "your-bucket-name";

    public void upload(String key, byte[] content) {
        PutObjectRequest request = PutObjectRequest.builder()
            .bucket(bucketName)
            .key(key)
            .build();
        s3Client.putObject(request, RequestBody.fromBytes(content));
    }

    public byte[] download(String key) {
        GetObjectRequest request = GetObjectRequest.builder()
            .bucket(bucketName)
            .key(key)
            .build();
        return s3Client.getObjectAsBytes(request).asByteArray();
    }

    public void delete(String key) {
        DeleteObjectRequest request = DeleteObjectRequest.builder()
            .bucket(bucketName)
            .key(key)
            .build();
        s3Client.deleteObject(request);
    }
}

このサービスではシンプルにアップロード・ダウンロード・削除を実装しています。キーはオブジェクトのファイル名やパスに直筆し、バケット内で一意である必要があります。オブジェクトにはメタデータ【Content-Typeなど】を付加することもできます。

プレサインドURLを生成するS3Presigner

S3のプレサインドURL【Presigned URL】を利用すると、一定時間だけ有効なアクセス用URLを登録できます。例えば、Webアプリから直接ブラウザにアップロードさせたり、期限付きダウンロードリンクを生成するのに便利です。AWS SDK v2ではS3Presignerクラスが提供されています。

S3Presignerの作成

S3Presignerはリージョンと認証情報を指定して生成します。SDKのドキュメントでは以下のように示されています。

import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.presigner.S3Presigner;

AwsBasicCredentials credentials = AwsBasicCredentials.create("YOUR_ACCESS_KEY", "YOUR_SECRET_KEY");
S3Presigner presigner = S3Presigner.builder()
    .region(Region.AP_NORTHEAST_1)
    .credentialsProvider(StaticCredentialsProvider.create(credentials))
    .build();

認証情報を開発環境以外でコードに埋め込むのは推奨されません。実際には環境変数やSTSの一時クレデンシャルを利用してください。

GET用プレサインドURLの生成

オブジェクトのダウンロードリンクを生成する例です。S3PresignerからGetObjectRequestを作成し、GetObjectPresignRequestに有効期限を指定します。

import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.presigner.model.GetObjectPresignRequest;
import java.time.Duration;

GetObjectRequest getRequest = GetObjectRequest.builder()
    .bucket(bucketName)
    .key(key)
    .build();

GetObjectPresignRequest presignRequest = GetObjectPresignRequest.builder()
    .signatureDuration(Duration.ofMinutes(10)) // 10分間有効
    .getObjectRequest(getRequest)
    .build();

String presignedUrl = presigner.presignGetObject(presignRequest)
    .url()
    .toString();

signatureDurationでは有効期限をDurationで指定します。S3のURLはjava.net.URLとして取得できるので、Webアプリやメール本文にそのまま挿入できます。

PUT用プレサインドURLの生成

オブジェクトのアップロード用URLを生成する場合はPutObjectRequestPutObjectPresignRequestを使用します。

import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.presigner.model.PutObjectPresignRequest;

PutObjectRequest putRequest = PutObjectRequest.builder()
    .bucket(bucketName)
    .key(key)
    .contentType("application/octet-stream")
    .build();

PutObjectPresignRequest presignRequest = PutObjectPresignRequest.builder()
    .signatureDuration(Duration.ofMinutes(5))
    .putObjectRequest(putRequest)
    .build();

String uploadUrl = presigner.presignPutObject(presignRequest)
    .url()
    .toString();

生成されたURLに対して、クライアントはHTTP PUTでファイルを送信するだけでS3にアップロードできます。Content-Typeを指定しておくとアップロード時のメタデータも設定されます。

サービスクラスへの統合

これらのプレサインドURL生成をサービスクラスに統合し、Spring Controllerから利用すると、バックエンドがS3への実際のデータ転送を行わずに済むため、効率的にファイルの受け渡しができます。

概念図

以下の図は、Spring BootアプリケーションがS3にファイルをアップロードし、プレサインドURLを生成してクライアントに提供する流れを示した概念図です。

S3の概念図: Client (Browser/App)、Spring Bootアプリケーション、Amazon S3バケットを示す図

まとめ

  • Amazon S3はバケットとオブジェクト単体のストレージであり、Spring Bootから扱う際はAWS SDK v2を利用します。
  • GradleのBOMを使ってsoftware.amazon.awssdk:s3モジュールを実装し、application.ymlでリージョンや認証情報を管理します。
  • S3Configurationにより高速輸送、パススタイルアクセス、チェックサム検証、チャンク転送署号などのカスタム設定が可能です。
  • S3Presignerを使うと、期限付きURLで安全にファイルのアップロードやダウンロードを姿更できます。
  • 設定を適切に行うことで、アプリケーションの要件や環境に合わせた柔軟なS3連携が実現できます。ぜひ今回紹介した方法を参考に、自分のSpring Bootプロジェクトに組み込んでみてください。

是非フォローしてください

最新の情報をお伝えします

類似投稿