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.ymlやapplication.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クライアントの動作を細かく制御できます。主なカスタム項目と役割を表にまとめます。
| 設定項目 | デフォルト | 説明 |
|---|---|---|
accelerateModeEnabled | false | Amazon S3 Transfer Accelerationを有効化。CloudFront経由で高速アップロードする場合に利用します。 |
pathStyleAccessEnabled | false | バケット名をURLパスとして指定するパススタイルアクセスを許可します。リージョンのDNS名解決制約やローカルスタック用に有効にすることがあります。 |
checksumValidationEnabled | true | サーバーから返されるEtagやチェックサムを検証し、データ破損を防ぎます。 |
chunkedEncodingEnabled | true | マルチパートアップロード時にチャンク転送署号を行います。 |
useArnRegionEnabled | false | バケットARNに含まれるリージョンを使用するかどうか。クロスリージョンS3にアクセスするときに設定します。 |
useExpectContinueEnabled | true | HTTP 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を生成する場合はPutObjectRequestとPutObjectPresignRequestを使用します。
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を生成してクライアントに提供する流れを示した概念図です。

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