处理文件上传
在表单中使用multipart/form-data上传文件
在web应用程序中上传文件的标准方式是使用指定multipart/form-data 编码的表单, 这样让你能混合标准表单数据和附件数据。
注意: 表单提交必须用
POSTHTTP方法(不能用GET)。
我们从写一个HTML表单开始:
@helper.form(action = routes.Application.upload, 'enctype -> "multipart/form-data") {
<input type="file" name="picture">
<p>
<input type="submit">
</p>
}
现在使用一个multipartFormData body解析器定义upload action:
def upload = Action(parse.multipartFormData) { request =>
request.body.file("picture").map { picture =>
import java.io.File
val filename = picture.filename
val contentType = picture.contentType
picture.ref.moveTo(new File(s"/tmp/picture/$filename"))
Ok("File uploaded")
}.getOrElse {
Redirect(routes.Application.index).flashing(
"error" -> "Missing file")
}
}
ref 属性给你一个到TemporaryFile的参考。这是mutipartFormData 解析器处理文件上传的默认方式。
注意: 你也可以使用
anyContentbody解析器,作为request.body.asMultipartFormData来检索。
最后, 添加一个POST 路由:
POST / controllers.Application.upload()
直接文件上传
另一个上传文件到服务器的方式是在表单中使用Ajax来异步上传文件。在这种情况下请求体不再是multipart/form-data, 但纯粹只包含文件内容。
在这种情况下我们可以只用一个body解析器来保存请求体内容到文件。例如, 使用temporaryFile body 解析器:
def upload = Action(parse.temporaryFile) { request =>
request.body.moveTo(new File("/tmp/picture/uploaded"))
Ok("File uploaded")
}
编写你自己的body解析器
如果你不想经过临时文件缓存而是直接处理上传的文件, 你可以自己写一个BodyParser。在这种情况下,你可以接收数据块,自由决定如何处理。
如果你想使用multipart/form-data 编码, 你仍可以使用默认的mutipartFormData 解析器,通过提供你自己的PartHandler[FilePart[A]],接收部分标头, 然后提供一个Iteratee[Array[Byte], FilePart[A]] 来生成正确的FilePart。