古いSDKに用意されていたAmazonS3Clientクラスの使用はDeprecated扱いになっており、 AmazonS3ClientBuilderを使え、とリファレンスに書かれていますが、日本語の文献が少ないようなので、備忘として残しておきます。
サンプルコード
package s3test;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.Protocol;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder.EndpointConfiguration;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.DeleteObjectsRequest;
import com.amazonaws.services.s3.model.DeleteObjectsRequest.KeyVersion;
import com.amazonaws.services.s3.model.DeleteObjectsResult;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.services.s3.model.S3ObjectInputStream;
public class S3Access {
private static final String ENDPOINT_URL = "https://s3-ap-northeast-1.amazonaws.com";
private static final String REGION = "ap-northeast-1";
private static final String ACCESS_KEY = "【アクセスキー】";
private static final String SECRET_KEY = "【シークレットキー】";
//--------------------------------------------------
// アップロード
//--------------------------------------------------
public void putObject(String bucketName, String objectKey, int objectSize, InputStream is) throws Exception {
// クライアント生成
AmazonS3 client = getClient(bucketName);
ObjectMetadata metadata = new ObjectMetadata();
// 念のためサイズだけセットしておく(不整合ならException)
metadata.setContentLength(objectSize);
// アップロード
client.putObject(bucketName, objectKey, is, metadata);
}
//--------------------------------------------------
// ダウンロード
//--------------------------------------------------
public S3ObjectInputStream getObject(String bucketName, String objectKey) throws Exception {
// クライアント生成
AmazonS3 client = getClient(bucketName);
// ダウンロード
S3Object s3Object = client.getObject(bucketName, objectKey);
return s3Object.getObjectContent();
}
//--------------------------------------------------
// 一括削除
//--------------------------------------------------
public List<String> deleteObjects(String bucketName, List<String> objectKeys) throws Exception {
// クライアント生成
AmazonS3 client = getClient(bucketName);
List<KeyVersion> keys = new ArrayList<KeyVersion>();
objectKeys.forEach(obj -> keys.add(new KeyVersion(obj)));
// ファイル削除
DeleteObjectsRequest request = new DeleteObjectsRequest(bucketName).withKeys(keys);
DeleteObjectsResult result = client.deleteObjects(request);
// 削除したオブジェクトのキーを取得
List<String> deleted = new ArrayList<String>();
result.getDeletedObjects().forEach(obj -> deleted.add(obj.getKey()));
return deleted;
}
//--------------------------------------------------
// クライアント生成
//--------------------------------------------------
private AmazonS3 getClient(String bucketName) throws Exception {
// 認証情報
AWSCredentials credentials = new BasicAWSCredentials(ACCESS_KEY, SECRET_KEY);
// クライアント設定
ClientConfiguration clientConfig = new ClientConfiguration();
clientConfig.setProtocol(Protocol.HTTPS); // プロトコル
clientConfig.setConnectionTimeout(10000); // 接続タイムアウト(ms)
// エンドポイント設定
EndpointConfiguration endpointConfiguration = new EndpointConfiguration(ENDPOINT_URL, REGION);
// クライアント生成
AmazonS3 client = AmazonS3ClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(credentials))
.withClientConfiguration(clientConfig)
.withEndpointConfiguration(endpointConfiguration).build();
if(!client.doesBucketExist(bucketName)) {
// バケットがなければException
throw new Exception("S3バケット[" + bucketName + "]がありません");
}
return client;
}
}
補足
-
アップロード/ダウンロードするオブジェクトはInputStream経由で受け渡していますが、必要に応じてファイルやbyte配列で受け渡すように変更すると良いでしょう。
-
分割アップロードなどで使うTransferManagerクラスもDeprecated扱いになっているので、代わりにTransferManagerBuilderクラスを使います。
-
一括削除では削除したオブジェクトのキーの値が返ってきますが、削除対象のオブジェクトが存在しなかったものについても、削除されたとみなしてキーの値が返ってくるようです。なお、一括削除できるのは同時に1,000件までです。それを超えるとキーの異常を示すエラーが返ってきます。
-
サンプルコードですのでアクセスキー/シークレットキーをコードにベタ書きしていますが、EC2上で実行するのであればIAM Roleを使い(後述)、AWS外で実行するのであればDB等に保存して定期的(90日以内)に入れ替えできるようにしておいたほうが良いでしょう。
※アップロードするデータを暗号化する場合は、以下の記事を参照してください。
AWS SDK for Javaを使ってS3にアップロードするデータを暗号化/SSE-KMS編
※EC2上でアプリケーションを実行する場合は、以下の記事を参照してください。
EC2 IAM Role環境でSSE-KMS暗号化を使ってS3バケットにアクセスする(AWS SDK for Java)
データを暗号化しない場合は、暗号化キー(CMK)にIAM Roleをアタッチする作業は不要です。