Scala Playframework S3にファイルアップロードを行う

個人開発したアプリの宣伝
目的地が設定できる手帳のような使い心地のTODOアプリを公開しています。
Todo with Location

Todo with Location

  • Yoshiko Ichikawa
  • Productivity
  • Free

スポンサードリンク

2.x系のAWS SDK for JavaでScala + Playframework + S3アップロードを行ったのでメモしておきます。

AWS SDK for Java 2.x

AWS SDK for Java 2.0 開発者ガイド - AWS SDK for Java バージョン 2


依存ライブラリの導入

僕の環境では40分ほどbuildに時間を要した笑

libraryDependencies += "software.amazon.awssdk" % "aws-sdk-java" % "2.13.27"
libraryDependencies += "software.amazon.awssdk" % "s3" % "2.13.27"

ライブラリバージョンは以下から確認すればよい。

GitHub - aws/aws-sdk-java-v2: The official AWS SDK for Java - Version 2

aws-sdk-java-v2/services at master · aws/aws-sdk-java-v2 · GitHub


SDKの利用

import java.nio.file.Path
import play.api.Configuration
import software.amazon.awssdk.auth.credentials.{AwsSessionCredentials, StaticCredentialsProvider}
import software.amazon.awssdk.core.sync.RequestBody
import software.amazon.awssdk.regions.Region
import software.amazon.awssdk.services.s3.S3Client
import software.amazon.awssdk.services.s3.model.{Bucket, ListBucketsRequest, PutObjectRequest}

object MyS3Client {

  val bucketName = "YOUR_S3_BUCKET_NAME"
  val directory = "S3DIRECTORY"
  val accessKey = "YOUR_ACCESS_KEY"
  val secretKey = "YOR_SECRET"
  val s3 = S3Client.builder().region( Region.AP_NORTHEAST_1 ).credentialsProvider(
    StaticCredentialsProvider.create(
      AwsSessionCredentials.create(accessKey, secretKey, "")
    )
  ).build()

  def put(fileName: String, path: Path) = {
    s3.putObject(PutObjectRequest.builder().bucket( bucketName ).key(directory+fileName).acl("public-read")
      .build(),
      RequestBody.fromFile(path) )
  }
}

regionメソッドはenumで定義できるので、指定のリージョンを選択すればよい。

PutObjectRequestkeyメソッドはS3のパスも含めたオブジェクト名(ファイル名)を渡す。

aclは上の例ではWebホスティング公開用でpublic-readを渡しています。

RequestBodyから生えるメソッドは色々種類があるので、書き込み対象のオブジェクトの用途に応じたメソッドを選択すれば良い。上記の例では、サーバ上に配置されているファイルを指定してS3にアップロードしています。


ブラウザからのファイルアップロード -> S3へ保存

def create() = Action(parse.multipartFormData){ implicit request =>
  request.body.files.map { file =>
    val filename = file.filename
    val destFile = new File(s"/tmp/$filename")
    val destPath = file.ref.moveTo(destFile)
    MyS3Client.put(filename, destPath )
    destPath.toFile.delete()
}

アップロードされたTemporaryFileからS3へputする方法が分からなかったので、一度、/tmpに書きこんでからS3にputしています(^_^;)

destPath.toFile.delete()は不要なファイルのお掃除。