📫

【Scala】PlayFrameworkで複数ファイルのリクエストを受け取る

2022/01/25に公開

概要

フロントエンドからmultipart/form-dataでファイルが添付されたリクエストを送った際に、ScalaのPlayFrameworkでどうやって受け取るかのまとめです。

対応方法

  • こちらのPlayFrameworkのドキュメントにある通り、Action(parse.multipartFormData)をControllerで設定することにより、requestからformの値と添付ファイルを受け取ることができます。
  • こちらのstackoverflowの記事にある通り、request.body.filesで添付された全ファイルを受け取ることができます。ファイルを格納した変数名は、指定しなくても大丈夫でした。

実装サンプル

フロントエンド側では以下のように、titledetailreferensFilesの三項目をfetchで送信します。

sample.js
  async function samplePost(title, detail, files) {
    // フォームデータのセット
    const postData = new FormData();
    postData.append("title", title);
    postData.append("detail", detail);
    files.forEach((file) => {
      postData.append("referenceFiles[]", file);
    });
    // 送信
    const url = $config.API_HOST + "/sample/filePost";
    const params = {
      method: "POST",
      headers: {
        "Content-Type": "multipart/form-data",
      },
      body: postData,
    };
    // deleteしてる理由は「https://qiita.com/risto24/items/50ffafd0e045b2c0709f」を参照のこと
    delete params.headers["Content-Type"];
    const res = await fetch(url, params);
  }

以下がPlayFrameworkでのリクエスト受け取りです。

SampleController.scala
def samplePost() = Action(parse.multipartFormData) { implicit request =>
  // ファイル以外のForm項目をチェック(記載は割愛)
  sampleRequestForm.bindFromRequest().fold(
    errors => BadRequest(errors.errorsAsJson),
    form => {
      // 添付されたファイルの受け取り
      val files = request.body.files.map(file => {
        // java.io.File型に変換
        file.ref.path.toFile
      })
      // 後続処理は割愛
      ・
      ・
    }
  )
}

Discussion