unfilteredでファイルアップロード

サポートしてくれてるのですごく簡単です。

build.sbtに以下を追加すれば使えるようになります。

"net.databinder" %% "unfiltered-uploads" % "0.5.1"

実際の例は↓な感じ。 アップロードしたファイルの中身を表示するだけですが・・・。

import scala.io.Source
import unfiltered.request._
import unfiltered.response._
import util.Properties

class Uploader extends unfiltered.filter.Plan {
  def intent = {
    case GET(_) => Ok ~> view(None, Nil)
    case POST(Path(_) & MultiPart(req)) => MultiPartParams.Streamed(req).files("file") match {
      case Seq(file, _*) if !file.name.isEmpty  =>
        view(Some(file.name), file.stream(t => Source.fromInputStream(t).getLines.toList))
      case f => view(None, Nil)
    }
  }

  def view(temp: Option[String], text: List[String]) = Html{
    <html>
      <body>
        <form method="POST" enctype="multipart/form-data">
          <input type="file" value="" name="file" />
          <input type="submit" />
        </form>
        { temp.map(t =>
          <div>
            <h1>File Name: {t}</h1>
            <pre>
              {text.zipWithIndex.map{case (line,index) => <div>{"%4d: %s".format(index + 1,  line)}</div>}}
            </pre>
          </div>
          ).toSeq }
      </body>
    </html>
  }
}

必要ないと思うけど、一応githubにあげてみた。
https://github.com/sassunt/unfiltered-upload-sample

上のコードの

file.stream(t => Source.fromInputStream(t).getLines.toList)

java.io.InputStreamを返してくれるけど、Source使う以外ないのかな

補足メモ:
自分が作ったときは、コンパイル時にMultiPartやらServletのクラスが不足してるよ
みたいなエラーが出て困ったけど・・・(エラーの詳細忘れた)
build.sbtに

"javax.servlet" % "servlet-api" % "2.5"

入れたらOKだった。