さっしーブログ

埼玉県在住のシステムエンジニアです。基本的には技術的な内容を中心に発信していきます。

PlayFrameworkで一時ファイルを作成せずに、レスポンスで返す方法

あるファイルをレスポンスで返したい。
けど、sendFile()を使用する場合、Fileインスタンスを引数に与えなくてはいけないし、
Fileインスタンスを作成するとなると物理ファイルのパスを指定したりしないとならない。
そしたら、一時的にファイルを作成しないといけないが一時的なファイルを作成した場合、
そのファイルを削除しなくてはいけない。

このような場合、PlayFrameworkで一時ファイルを作らなくてもレスポンスにファイルデータを載せて返却してあげる方法を掲載します。

目次

方法

読み込んだファイルのバイト配列からByteArrayInputStreamを生成して、
EnumeratorのfromStreamメソッドに渡したコンテンツをHttpレスポンスに入れてやる感じです。

サンプルコード

では、実際のサンプルコードを下記に掲載します。

val content = Enumerator.fromStream(new ByteArrayInputStream(in))
val encFileName = java.net.URLEncoder.encode(fileName, "UTF-8")
Ok.feed(content)
  .withHeaders(
  CONTENT_TYPE -> "application/pdf",
  CONTENT_DISPOSITION -> s"filename*=utf-8'ja'$encFileName"
  )

コード解説

new ByteArrayInputStream(in)

バイト配列の入力ストリームを生成します。
これはレスポンスで返すための入力データになります。

Enumerator.fromStream(・・・)

上記コードのバイト配列データを読み込んでEnumerator型のデータを作成します。

val encFileName = java.net.URLEncoder.encode(fileName, "UTF-8")

ここは今回の部分と関係ありませんが、日本語ファイル名が文字化けしないようにしています。

Ok.feed(content)

うまく説明できてないと思いますが、
Enumerator型のデータをストリーミングして送信します。
分割して送る感じですかね。。

最後に

Enumeratorを調べると、「Enumeratee」や「Iteratee」というキーワードが出てきて現状の知識では難しく感じました。
今後PlayFrameworkを学習していく中でPlayの知識や基礎知識がついてくれば飲み込みやすくなると思うのでもう少し学習を進めてから再度勉強してみようと思います。

以上