处理文件上传
在表单中使用multipart/form-data上传文件
在web应用程序中上传文件的标准方式是使用指定multipart/form-data
编码的表单, 这样让你能混合标准表单数据和附件数据。
注意: 表单提交必须用
POST
HTTP方法(不能用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
解析器处理文件上传的默认方式。
注意: 你也可以使用
anyContent
body解析器,作为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。