Scala + Lift + HTML5
http://d.hatena.ne.jp/norio515/20101218/1292664211 を参考に、lift でファイル uploader を作成してみた。
ただし、HTML5 で追加されたフォームの機能を使い、複数ファイルのアップロードが可能であるようにした。
手順
HtmlProperties、XHTML、および HTML5 | Lift Space | Assembla にあるように、
Boot.scala に
LiftRules.htmlProperties.default.set((r: Req) =>new Html5Properties(r.userAgent))
を追加する。
- これで HTML5 の機能を使える。
はずなのだが、今回、これを追加しなくても、アプリケーションは問題なく作動した。
index.html は
<lift:surround with="default" at="content"> You can upload any file. <lift:UploadSnippet.upload form="POST" multipart="true"> <fieldset> <legend>uploadingfiles</legend> <span> <form:submit/> </span> <span> <form:upload/> </span> </fieldset> </lift:UploadSnippet.upload><br/><br/> </lift:surround>
のように書く。
- fieldset タグと legend タグはなくてもよいが、
- span タグは必要。これがないと、input 要素が1つしか出力されない。
UploadSnippet.scala は
package ireiz.uploader.snippet import _root_.java.io.{File, FileOutputStream} import _root_.scala.xml.NodeSeq import _root_.net.liftweb.util.BindHelpers._ import _root_.net.liftweb.http.FileParamHolder import _root_.net.liftweb.http.S import _root_.net.liftweb.http.SHtml._ class Uploadsnippet { val filepath = "src/main/webapp/static/uploaded/" def upload(xhtml: NodeSeq): NodeSeq = { def save: FileParamHolder => Unit = { case FileParamHolder(_, _, fn, file) => { val dir = new File(filepath, fn) val output = new FileOutputStream(dir) { write(file) close } S.notice("Uploading succeeded.") } } bind("form", xhtml, "submit" -> submit("Save", () => ()), "upload" -> fileUpload(save, new BasicElemAttr("multiple", "multiple"))) } }
と書く。
- fileUpload メソッドの第2引数で、multiple 属性を与えるのが、ポイント。
- fileUpload メソッドは、アップロードされるファイル1つ1つにつき、呼び出される
- クラス名は最初の文字以外、小文字でなければならない。この点間違えると、
Error processing snippet uploadsnippet.upload. Reason: Class Not Found XML causing this error:
とのエラーメッセージがブラウザ上に表示される。(test mode の場合)